简体   繁体   中英

comparing vector to vector of struct - c++

I have a program that creates a vector of 6 random numbers, and another vector that contains all numeric contents of a file. I need to compare the 6 numbers to the entire file vector to find all the matches.

I've managed to get my program working but it only seems to match the first number per line from my file, and doesnt loop over the rest of the line.

//struct to store data from file
struct past_results {
   std::string date;
   std::string winningnums;
};

 //vector containing the 6 random numbers  
 int size = 6;   
 std::vector<int> numbers(size);

 //data from struct goes into this vector
 std::vector<past_results> resultvec;
 
 //function to search vector and match with vector of 6 nums
 for (const struct &e : resultvec){

 //compares 'resultvec.winningnums' data to 'numbers' vector
 for(int i = 0; i < size; i++)
        if(std::stoi(e.winningnums) == numbers.at(i)){
            std::cout << "number found:" << numbers.at(i) << std::endl;
            ++numcount;
        }  
  }

Example output:

Numbers generated: 17 36 14 17 22 2 

Numbers from vec: 5,6,16,17,19,22,40
Numbers from vec: 6,16,23,34,35,40,37
Numbers from vec: 10,14,15,23,24,27,39
Numbers from vec: 12,23,28,2,36,40,18  //<--- should catch the 2 from this line
Numbers from vec: 10,2,24,31,36,47,41
Numbers from vec: 13,17,22,41,43,47,28
Numbers from vec: 2,11,28,29,31,39,24
number found:2
Numbers from vec: 4,12,15,39,45,47,22
Numbers from vec: 1,2,33,36,38,45,48   //<---- should catch 2 from this line
Numbers from vec: 2,15,16,17,25,26,44
number found:2

You can see my program only checks for the value once per line, and doesnt run through the entire line to check. It also only gets the matching number if it is the first number from the line. I need the program to search line by line, and find all of the matching numbers from each string. The file contents are in string form, gathered by a getline function from my file, I then convert these back to int using stoi::

how would I extend my for loop to include all data from the line and not just the first number?


EDIT

minimal example:

//struct to store data from file
struct foo {
   std::string b;
};


int main(){

   std::vector<foo> a;
   
   //vector of nums to compare
   std::vector<int> c;
    
   //find numbers in vector b that equal vector of struct foo(element x)
   if(c.at(i) == a.b.at(i))
   {
     //output matching nums
    
   }

 }

Instead of

struct foo {
   std::string b;
};

I would store the numbers that you read from the file in a container storing numbers, like std::vector<int> if you need to store them in the exact order they are present in the file. If you don't need to preserve the order you could also std::sort them to make searching faster by using a binary search algorithm. If you don't need to support storing duplicates, you could store the numbers in a std::unordered_set directly.

I don't know what you need so I'll show how you can store them as they are listed in the file and then use a std::unordered_set when checking if numbers you search for exists.

#include <iostream>
#include <sstream>
#include <unordered_set>
#include <vector>

//------------------------------------------------------------------------------
// a helper to discard a certain character from an istream
template<char Char> struct eat {};

template<char Char>
std::istream& operator>>(std::istream& is, const eat<Char>&) {
    if(is.peek() == Char) is.ignore();
    else is.setstate(std::ios::failbit);
    return is;
}
//------------------------------------------------------------------------------
// struct to store data from file
struct foo {
    std::vector<int> b;
    // ...other members...

    // return the stored numbers as an unordered_set to make searching easy
    std::unordered_set<int> get_as_set() const {
        return {b.begin(), b.end()};
    }
};

// read one `foo` from an istream:
std::istream& operator>>(std::istream& is, foo& f) {
    std::string line;
    if(std::getline(is, line)) {
        std::istringstream iss(line);
        f.b.clear();

        int number;
        while(iss >> number) {
            f.b.push_back(number);
            iss >> eat<','>{};
        }
    }
    return is;
}

// print one `foo` to an ostream:
std::ostream& operator<<(std::ostream& os, const foo& f) {
    auto it = f.b.begin();
    if(it != f.b.end()) {
        os << *it;
        for(++it; it != f.b.end(); ++it) {
            os << ',' << *it;
        }
    }
    return os;
}
//------------------------------------------------------------------------------
int main() {
    // an example file:
    std::istringstream file{
        R"aw(5,6,16,17,19,22,40
6,16,23,34,35,40,37
10,14,15,23,24,27,39
12,23,28,2,36,40,18
10,2,24,31,36,47,41
13,17,22,41,43,47,28
2,11,28,29,31,39,24
4,12,15,39,45,47,22
1,2,33,36,38,45,48
2,15,16,17,25,26,44
)aw"};

    // read the file into a vector<foo>:
    std::vector<foo> a;
    foo tmp;
    while(file >> tmp) {
        a.push_back(std::move(tmp));
    }

    // vector of nums to compare
    std::vector<int> c{7, 36, 14, 17, 22, 2};

    // find numbers in vector b that equal vector of struct foo(element x)
    for(const foo& f : a) {
        std::cout << f << '\n';  // print the `foo`
        auto s = f.get_as_set(); // get the numbers in `f` as a set

        for(int val : c) {
            // check if the set contains the values you search for:
            if(s.contains(val)) std::cout << val << " found\n";
            // s.contains(val) requires c++20 or greater, for earlier
            // versions, use `s.find(val) != s.end()`
        }
    }
}

Output:

5,6,16,17,19,22,40
17 found
22 found
6,16,23,34,35,40,37
10,14,15,23,24,27,39
14 found
12,23,28,2,36,40,18
36 found
2 found
10,2,24,31,36,47,41
36 found
2 found
13,17,22,41,43,47,28
17 found
22 found
2,11,28,29,31,39,24
2 found
4,12,15,39,45,47,22
22 found
1,2,33,36,38,45,48
36 found
2 found
2,15,16,17,25,26,44
17 found
2 found

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM