简体   繁体   中英

I need help fixing a code trying to find substring in a string

I'm trying to create a new string and write month names to it, then use it to check if I have already written the month name to a file. This is my code I'm trying to fix:

void writeToFile(RainStruct rainPerMonth[], int monthsInYear)
{
   // Create string variable
   string month;
  
   // Create and open file
   fstream rainFile("scramble.txt", ios::out);
  
   // Write into file, goes through each structure and writes it
   for (int count = 0; count < 11; count++)
   {
      // Set random number variable
      int randNum = rand() % 12;
  
      // Set string variable month to different random month names
      month += rainPerMonth[randNum].monthNames;
  
      // Call to checkMonth
      if (checkMonth(rainPerMonth, monthsInYear, randNum, month))
      {
         // Write months in random order to file
         rainFile << rainPerMonth[randNum].monthNames << " had " << rainPerMonth[randNum].monthRain    << " inches.\n";
      }
   }
  
    // Close, reopen, truncate, and close file again
    rainFile.close();
    rainFile.open("scramble.txt", ios::trunc);
    rainFile.close();
}

bool checkMonth(RainStruct rainPerMonth[], int monthsInYear, int randNum, string month)
{
    size_t pos = month.find(rainPerMonth[randNum].monthNames);
    if(pos != string::npos)
    {
       return true;
    }
    else
    {
       return false;
    }
}

It ends up printing some months twice, and doesn't print all months. What do I need to change to fix it to write all months to a file in random order (with their rain per month attached)? This is my full code: https://onlinegdb.com/ry6yO4a4 _ The specifications of the assignment is that I have to use a string variable to search for a substring inside a string, then check that it's not already there, then write the month to the file. He said I have to use a random generator and cannot hard code. This is the hint he gave us: http://www.cplusplus.com/reference/string/string/substr/

You could use the example from shuffle() function's reference to create a shuffled list of the month indexes and then write it out to the file. rand() doesn't guarantee unique indexes so it might return any number between [0, 11] , probably even repeating them.

#include <algorithm>
#include <array>
#include <iostream>
#include <random>
 
void print(const auto& a) {
    for (const auto e : a) { std::cout << e << ' '; }
    std::cout << "\n";
}
 
int main()
{
    std::array a{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    print(a);
 
    std::random_device rd;
    std::mt19937 gen{rd()};
 
    for (int i{}; i != 3; ++i) {
        std::ranges::shuffle(a, gen);
        print(a);
    }
    //Then just use a[0], a[1]...as the index to rainPerMonth[] and write it out to file
}

Output :

0 1 2 3 4 5 6 7 8 9 10 11 
10 4 6 7 8 11 2 5 9 1 3 0 
0 5 7 4 2 8 11 9 6 1 10 3 
10 8 5 7 9 4 2 6 11 1 3 0 

This makes most of what you need without adding more dependencies (although std's vectors and arrays are great):

struct RainStruct{
    RainStruct(std::string monthNames, int monthRain){
        this->monthNames = monthNames;
        this->monthRain = monthRain;
        }
    std::string monthNames;
    int monthRain;
    };
    
// Shuffle array
void shuffle_array(int arr[], int n)
{
 
    // To obtain a time-based seed
    unsigned seed = 0;
 
    // Shuffling our array
    shuffle(arr, arr + n,
            std::default_random_engine(seed));
 
    // Printing our array
    for (int i = 0; i < n; ++i)
        std::cout << arr[i] << " ";
    std::cout << std::endl;  // you wont need this
}

void writeToFile(RainStruct rainPerMonth[], int monthsInYear)
{
// Create integers array
int nums[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
shuffle_array(nums, 12);

for (int count = 0; count < 12; count++)
{
  // Set random number variable
  int randNum = nums[count]-1;

  std::cout << rainPerMonth[randNum].monthNames << " had " << 
  rainPerMonth[randNum].monthRain    << " inches.\n";
  }

}


int main()
{  
   
   RainStruct structSample[12] = { RainStruct("Jan", 1) , 
                                 RainStruct("Feb", 2) , 
                                 RainStruct("Mar", 3) , 
                                 RainStruct("Apr", 4) , 
                                 RainStruct("May", 5) , 
                                 RainStruct("Jun", 6) , 
                                 RainStruct("Jul", 7) , 
                                 RainStruct("Agu", 8) , 
                                 RainStruct("Sep", 9) , 
                                 RainStruct("Oct", 10) , 
                                 RainStruct("Nov", 11) , 
                                 RainStruct("Dec", 12) , 
                                 }; 
   writeToFile(structSample, 12);
}

Output:

3 8 11 7 12 1 5 10 6 4 2 9 
Mar had 3 inches.
Agu had 8 inches.
Nov had 11 inches.
Jul had 7 inches.
Dec had 12 inches.
Jan had 1 inches.
May had 5 inches.
Oct had 10 inches.
Jun had 6 inches.
Apr had 4 inches.
Feb had 2 inches.
Sep had 9 inches.

You can use your method to write the file

The problem is that a random number generator will generate the same number twice when you ask for a bunch of random numbers. Asking for 12 random numbers will find some missing and some repeated.

To fix this, you need to first build an array of the month numbers in random order where you make sure that all the months are in it and none are repeated. Otherwise, you will see the effect you mention.

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