Matching Numbers in 2 arrays c++ - c++

I'm writing a program which is intended to compare the numbers in 2 arrays and output the number of matches that there are.
RandomNumber.h
#pragma once
#include <iostream>
#include <cstdlib>
#include <ctime>
class RandomNumber
{
public:
void randomNumber();
int actualRandomNumber;
};
RandomNumber.cpp
#include "RandomNumberGenerator.h"
void RandomNumber::randomNumber()
{
actualRandomNumber = rand() % 66 + 1;
}
Game.h
#include "RandomNumberGenerator.h"
class Game
{
private:
int randomNumbers[6];
public:
void generateRandomNumbers();
void compareNumbers2();
};
Game.cpp
void Game::generateRandomNumbers()
{
RandomNumber create;
for (int i = 0; i < 6; i++)
{
create.randomNumber();
randomNumbers[i] = create.actualRandomNumber;
}
for (int i = 0; i < 6; i++)
{
std::cout << randomNumbers[i] << " ";
}
}
void Game::compareNumbers2()
{
int k = 0;
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
if (randomNumbers[i] == randomNumbers[j])
{
k++;
}
}
}
if (k > 0)
{
std::cout << "Congratulations you matched: " << k << " number(s)";
}
if (k == 0)
{
std::cout << "Unfortunatly you matched: " << k << " numbers";
}
}
Main.cpp
#include "Game.h"
#include "RandomNumberGenerator.h"
int main()
{
Game play;
srand (time(NULL));
play.generateRandomNumbers();
std::cout << std::endl << std::endl;
play.generateRandomNumbers();
std::cout << std::endl << std::endl;
play.compareNumbers2();
system("pause");
return 0;
}
The problem I'm having isn't in creating the arrays and filling them, I get two filled arrays with 2 different sets of random numbers, but for some reason when comparing them the number of matches it tells me I have is always about 6 or 8 when I in fact rarely have more than one or two if that.

The most obvious problem is that you only have one array.
class Game
{
...
int randomNumbers[6];
Where did you think the second array was?

Based on your code, I saw only 1 array. And in the function compareNumber2(), you compare each number with it once. Therefore, the result is the number of elements (e.g, 6).

Looking at code, I can say you will be getting 6 matches all the time, since you randomNumbers array will be overwritten in second step (when you try to generate random numbers second time)

There are actually two problems bigger and smaller:
You're comparing your array int randomNumbers[6] with itself.
Please don't call the object create. Its very wrong habit. Call the object of class RandomNumber i.e a randomNumber and take your random number from it like:
randomNumber.getValue()
Usually try to call the methods with verbs and objects with nouns it will be more natural don't you think?

You do no not compare two arrays. You compare one array, data member of class Game, with itself. You simply fill it two times.

Related

Function to randomly convert chars toupper case

Am revisiting an exercise from an online course where we created a 'Whale translator' which checks through each character that the user inputs and extracts / returns only the vowels.
I thought it would be fun to have the returned values capitalized at random so the whole thing would feel a little like Dory speaking whale (finding Nemo) so I created a function to take each character and convert them to caps based on whether a random number is odd or even. Thing is that I cannot get the program to acknowledge or use my function. Runs fine otherwise.
Could somebody give me a pointer as to where I'm going wrong?
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
char converter(char);
int main() {
std::cout << "WeELCooOmE ToOOoO the WHaALe translaAtoOor \n";
std::cout << "\n PlEaAsE EnntEer yoOur text tOo beEE trAanslaAateEd \n\n";
std::string input;
std::getline(std::cin, input);
std::cout << "\n";
std::vector<char> vowels;
vowels.push_back('a');
vowels.push_back('e');
vowels.push_back('i');
vowels.push_back('o');
vowels.push_back('u');
std::vector<char> whale_talk;
for (int i = 0; i < input.size(); i++) {
for (int j = 0; j < vowels.size(); j++) {
if (input[i] == vowels[j]) {
whale_talk.push_back(input[i]);
}
}
}
std::cout << "HeEre iS yOoUr translaAtiOn..\n\n";
for (int k = 0; k < whale_talk.size(); k++) {
converter(whale_talk[k]);
std::cout << whale_talk[k];
}
std::cout << "\n";
}
char converter(char x) { //function to convert characters toupper based on random number generation.
int rando = rand() % 100;
if (rando % 2 == 0) {
x = toupper(x);
return x;
}
else {
return x;
}
}
You converter function is returning the modified char but you never use the returned value in the for loop:
converter(whale_talk[k]);
You need to do:
whale_talk[k] = converter(whale_talk[k]);
Here's a demo.
Alternatively, you can leave the call site as it is, but pass the char to be converted by reference, like this:
void converter(char &x) { // << pass by reference
// and modify x, but don't return it
}
Here's a demo.
You ignore the retun value of converter, so it has no effect.
This
converter(whale_talk[k]);
std::cout << whale_talk[k];
should be
std::cout << converter(whale_talk[k]);

Sorting my 2d array in c++

My homework program has to write random numbers for arrival time and burst time into a file. Then after they are written, it reads the file and sorts the contents.
I figured setting up a 2d array would be the easiest way for me to go about this. But I am unsure on how to implement my sort so that if an arrival time swaps places then burst time of that arrival goes along for the ride.
I feel like I worded that poorly, but a basic example would be:
array[3][10] > array[2][23]
So since second array has an earlier arrival time I need both its arrival 2 and its burst 23 to move before array[3][10], but I need this do that and compare 100 inputs.
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <fstream>
const int max = 100;
using namespace std;
int main()
{
multimap<int [][]> myMap;
int randomBurst[max];
int arrivalTime[max];
int line[max][2];
int first = 0;
for (int i = 0; i < 100; i++)
{
if (i < 100)
{
ofstream write("Schedule.txt", ios::app);
randomBurst[i] = rand() % 1000;
arrivalTime[i] = rand() % 1000;
write << arrivalTime[i] << " " << randomBurst[i] << endl;
}
}
ifstream read("Schedule.txt");
for (int i = 0; i <= max; i++)
{
for (int j = 0; j < 2; j++)
{
read >> line[i][j];
cout << line[i][j] << " " ;
}
cout << endl;
}
cout << endl;
cout << endl;
for (int i = 0; i <= max; i++)
{
for (int j = 0; j < 2; j++)
{
myMap.insert(pair<int[][]>(line[i][j]);
}
cout << endl;
}
system("pause");
return 0;
}
My code sets up my array correctly after it reads the written file content, but I'm kind of lost what I should implement for a sort.
Well coming forward with this, mainly left that comment to be able to find this question faster on my laptop.
Like I said in the comment, if you want a presorted, by key value 2D "array", the quickest manner in which you could do this is with the map container., and if you really need the internal points to be ordered, and you will be using multiple entries within it, lets say entries 2,30 2,12 ... You could either build a map of vectors, or arrays, or use a Multimap. Not too sure of this data structure, as I have never really had a reason to use it as of yet. Referenced here http://www.cplusplus.com/reference/map/multimap/
The above will provide you with the sorting done for you, and the reason why I recommended a vector is the lack of order within it, and not sure if the 'bursts?' are to be ordered as well.
EDIT:
Forgot to mention, that a map will not hold more than one key of any given value, so if you are, again, inputting multiple points a above, then you will. if implementing things as you were before, overwrite things.
EDIT:
So this is more or less the fix I think I have, but you are working around this in a very indirect manner, that is hard to follow honestly.
#include <map>
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <fstream>
using namespace std;
const int MAX = 100;
int main()
{
multimap<int,int> myMap;
int randomBurst[100];
int arrivalTime[100];
int line[100][2];
int first = 0;
for (int i = 0; i < 100; i++)
{
if (i < 100)
{
ofstream write("Schedule.txt", ios::app);
randomBurst[i] = rand() % 1000;
arrivalTime[i] = rand() % 1000;
write << arrivalTime[i] << " " << randomBurst[i] << endl;
}
}
ifstream read("Schedule.txt");
for (int i = 0; i <= 100; i++)
{
for (int j = 0; j < 2; j++)
{
read >> line[i][j];
cout << line[i][j] << " " ;
}
cout << endl;
}
// cout << endl;
// cout << endl;
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 2; j++)
{
//Attain the value in the index, and the held value within it.
myMap.insert(pair<int, int> (line[i][j], line[i][j]));
}
cout << endl;
}
// system("pause");
return 0;
This fixes the insertion point, just because you give it an array it does not mean that the program will take that as a pair, as the first index is a point to another array in itself. And so on. I recommend starting off wiht a map object instead, as the multimap makes things a bit annoying, if you are familiar with the vector containers then use that instead within the map to log multiple values.

Recursive generation of all “words” of arbitrary length

I have a working function that generates all possible “words” of a specific length, i.e.
AAAAA
BAAAA
CAAAA
...
ZZZZX
ZZZZY
ZZZZZ
I want to generalize this function to work for arbitrary lengths.
In the compilable C++ code below
iterative_generation() is the working function and
recursive_generation() is the WIP replacement.
Keep in mind that the output of the two functions not only differs slightly, but is also mirrored (which doesn’t really make a difference for my implementation).
#include <iostream>
using namespace std;
const int alfLen = 26; // alphabet length
const int strLen = 5; // string length
char word[strLen]; // the word that we generate using either of the
// functions
void iterative_generation() { // all loops in this function are
for (int f=0; f<alfLen; f++) { // essentially the same
word[0] = f+'A';
for (int g=0; g<alfLen; g++) {
word[1] = g+'A';
for (int h=0; h<alfLen; h++) {
word[2] = h+'A';
for (int i=0; i<alfLen; i++) {
word[3] = i+'A';
for (int j=0; j<alfLen; j++) {
word[4] = j+'A';
cout << word << endl;
}
}
}
}
}
}
void recursive_generation(int a) {
for (int i=0; i<alfLen; i++) { // the i variable should be accessible
if (0 < a) { // in every recursion of the function
recursive_generation(a-1); // will run for a == 0
}
word[a] = i+'A';
cout << word << endl;
}
}
int main() {
for (int i=0; i<strLen; i++) {
word[i] = 'A';
}
// uncomment the function you want to run
//recursive_generation(strLen-1); // this produces duplicate words
//iterative_generation(); // this yields is the desired result
}
I think the problem might be that I use the same i variable in all the recursions. In the iterative function every for loop has its own variable.
What the exact consequences of this are, I can’t say, but the recursive function sometimes produces duplicate words (e.g. ZAAAA shows up twice in a row, and **AAA gets generated twice).
Can you help me change the recursive function so that its result is the same as that of the iterative function?
EDIT
I realised I only had to print the results of the innermost function. Here’s what I changed it to:
#include <iostream>
using namespace std;
const int alfLen = 26;
const int strLen = 5;
char word[strLen];
void recursive_generation(int a) {
for (int i=0; i<alfLen; i++) {
word[a] = i+'A';
if (0 < a) {
recursive_generation(a-1);
}
if (a == 0) {
cout << word << endl;
}
}
}
int main() {
for (int i=0; i<strLen; i++) {
word[i] = 'A';
}
recursive_generation(strLen-1);
}
It turns out you don't need recursion after all to generalize your algorithm to words of arbitrary length.
All you need to do is "count" through the possible words. Given an arbitrary word, how would you go to the next word?
Remember how counting works for natural numbers. If you want to go from 123999 to its successor 124000, you replace the trailing nines with zeros and then increment the next digit:
123999
|
123990
|
123900
|
123000
|
124000
Note how we treated a number as a string of digits from 0 to 9. We can use exactly the same idea for strings over other alphabets, for example the alphabet of characters from A to Z:
ABCZZZ
|
ABCZZA
|
ABCZAA
|
ABCAAA
|
ABDAAA
All we did was replace the trailing Zs with As and then increment the next character. Nothing magic.
I suggest you now go implement this idea yourself in C++. For comparison, here is my solution:
#include <iostream>
#include <string>
void generate_words(char first, char last, int n)
{
std::string word(n, first);
while (true)
{
std::cout << word << '\n';
std::string::reverse_iterator it = word.rbegin();
while (*it == last)
{
*it = first;
++it;
if (it == word.rend()) return;
}
++*it;
}
}
int main()
{
generate_words('A', 'Z', 5);
}
If you want to count from left to right instead (as your example seems to suggest), simply replace reverse_iterator with iterator, rbegin with begin and rend with end.
You recursive solution have 2 errors:
If you need to print in alphabetic order,'a' need to go from 0 up, not the other way around
You only need to print at the last level, otherwise you have duplicates
void recursive_generation(int a) {
for (int i=0; i<alfLen; i++)
{ // the i variable should be accessible
word[a] = i+'A';
if (a<strLen-1)
// in every recursion of the function
recursive_generation(a+1); // will run for a == 0
else
cout << word << '\n';
}
}
As I am inspired from #fredoverflow 's answer, I created the following code which can do the same thing at a higher speed relatively.
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
void printAllPossibleWordsOfLength(char firstChar, char lastChar, int length) {
char *word = new char[length];
memset(word, firstChar, length);
char *lastWord = new char[length];
memset(lastWord, lastChar, length);
int count = 0;
std::cout << word << " -> " << lastWord << std::endl;
while(true) {
std::cout << word << std::endl;
count += 1;
if(memcmp(word, lastWord, length) == 0) {
break;
}
if(word[length - 1] != lastChar) {
word[length - 1] += 1;
} else {
for(int i=1; i<length; i++) {
int index = length - i - 1;
if(word[index] != lastChar) {
word[index] += 1;
memset(word+index+1, firstChar, length - index - 1);
break;
}
}
}
}
std::cout << "count: " << count << std::endl;
delete[] word;
delete[] lastWord;
}
int main(int argc, char* argv[]) {
int length;
if(argc > 1) {
length = std::atoi(argv[1]);
if(length == 0) {
std::cout << "Please enter a valid length (i.e., greater than zero)" << std::endl;
return 1;
}
} else {
std::cout << "Usage: go <length>" << std::endl;
return 1;
}
clock_t t = clock();
printAllPossibleWordsOfLength('A', 'Z', length);
t = clock() - t;
std:: cout << "Duration: " << t << " clicks (" << ((float)t)/CLOCKS_PER_SEC << " seconds)" << std::endl;
return 0;
}

Class Rolling Dice program

I need to write C program for rolling dice using class Dice. The main requirement is that I need to use this main, editing it:
int main()
{
Dice* ptrDice;
???
for (int i = 0; i < 5; i++)
{
???? // roll the 5 dice
???? // print the outcome
}
}
I just cannot get how to use pointers here. Can anyone help, pls?!
Here is my code but it's not working :(
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
class Dice{
public:
Dice();
int getNums();
void Roll();
private:
int nNums;
};
Dice::Dice(){
nNums=5;
}
int Dice::getNums()
{
return nNums;
}
void Dice::Roll()
{
nNums = rand()%6 + 1;
}
int main()
{
Dice* ptrDice = new Dice;
ptrDice -> getNums();
for (int i = 0; i < 5; i++)
{
getNums[i] = rand()%6 + 1; // roll the 5 dice
cout << "You rolled: ";
cout << ptrDice->getNums() << setw(4);
cout << endl; // print the outcome
}
}
My main trouble is to use that ptrDice and printing it in main function, I guess!
You're making this more complicated than it needs to be.
A simple Dice object needs no data members and only one member function. If you're using the rand() function, the constructor should seed the random number generator with srand(seed). The Roll() function should return the number rolled as an int. You don't need the getNums() function at all, which will only return 5 as your class is defined.
class Dice() {
public:
int roll() { return rand() % 6 + 1; }
};
...
int main() {
Dice* ptrDice = new Dice;
for (int i=0; i<5; i++) {
cout << "You rolled" << ptrDice->roll() << '\n';
}
delete ptrDice;
}
You could expand this class to simulate multiple dice with any number of sides. Then you could use integer data members to retain the number of dice and their number of sides.

How to solve 8 queens 1D array with brute force?

I was given an assignment to modify an 8 Queens program to use a 1D array and to use brute force (already did backtracking). I've come up with the following code:
#include <cmath>
#include <iostream>
using namespace std;
bool ok(int board[8]){
for(int j = 0; j <= 7; j++){ //check for repeating digits
cout << "ok loop 1"<<endl;
for (int k = 0; k <= 7; k++)
{
cout << "ok loop 2"<<endl;
if (board[k] = board[j]){ return false; }
}
}
for(int c = 7; c >= 0; c--){ //check if position is safe
cout << "ok loop 3"<<endl;
//int r = 0;
for(int i = 1; i <= c; i++){
cout << "ok loop 4"<<endl;
if(board[c-i] == c)
return false;
else if ((board[c]-i)>0 && board[c-i]-i == 1)
return false;
else if ((board[c]+i)<=7 && board[c-i]+i == 1)
return false;
} // for loop
} // for loop
return true;
} // ok
void print(int board[8], int c){
cout << "Solution " << c << ": " << endl;
for(int i = 0; i < 8; i++){
{
cout << board[i] <<" ";
}
}
cout << endl;
}
int main ()
{
int b[8]={0}; //initialize the array
int count = 0;
for(b[0]=0; b[0]<8; b[0]++)
for(b[1]=0; b[1]<8; b[1]++)
for(b[2]=0; b[2]<8; b[2]++)
for(b[3]=0 ; b[3]<8; b[3]++)
for(b[4]=0; b[4]<8; b[4]++)
for(b[5]=0; b[5]<8; b[5]++)
for(b[6]=0; b[6]<8; b[6]++)
for(b[7]=0; b[7]<8; b[7]++)
if(ok(b))
{
count++;
print(b, count);
}
system("PAUSE");
return 0;
}
It keeps looping forever and I am not sure why. Would anyone mind helping me?
There's a few things that could be improved:
If you passed a reference to a constant array of eight chars to ok() instead of just a pointer to non-const ints, the compiler could have told you about one of the issues.
How many different positions can a queen have? I'd say 64, though your code suggests eight. I'd start with documenting the actual meaning of variables and constants throughout your code, because you seem to be confused there yourself.
You check if board[x] is board[y], but with x and y being equal, and from that you claim that there are repeating digits.
You make a difference between the different queens. In other words, your program will find all permutations of how the queens could be positioned on the same eight positions. This is not incorrect, but inefficient. If you fix the number of positions, that will make a noticeable difference.