Working with vectors and loops - c++

sorry to post a student question here. I'm not looking for a quick solution, I'm looking to understand. Comments in my code will explain the same, but here's a plain text version:
This is the beginning of a "LoShu Magic Square", I'm not to the addition of all parts of the matrix I'm making, I'm stuck at trying to verify that the same number has not been put into the rows before. My idea was to use one vector to "test" numbers that had been entered so far, so it does not need to be multi-dimensional (none of them are, but I don't care about the limit on the tester).
As-is the code will take the first number into the test vector, go to the check function, realize that number is there (which it should, haven't hashed out where to add the initial value), and after that initial check it will take ANY other value between 1-9, including repeats, which is bad. Help please? Why does it stop recognizing values inside the test vector after the initial round?
Separate link to code if it's maybe easier to read there: http://ideone.com/Dzh4mJ
#include<iostream> // This is the beginning of a "LoShu magic square" program for class, currently my
#include <vector> // goal is simply getting vectors to check whether or not a number has already been
using namespace std; // entered, and if so to go back and ask for another one. As-is it does not work
// through the first iteration. It recognizes the first number, says it's already in
bool theCheckening(vector<int>, int ); // and proceeds to take ANY numbers afterwards, repeats and all.
int main () {
int tester;
vector<int> loShu1; // Rows 1-3 of a "square"
vector<int> loShu2;
vector<int> loShu3;
vector<int> testCaseOut(1,0); // Test vector to iterate inside check function
do {
do{
cout << "Enter 1-9: "; // Working as intended, makes sure no number besides 1-9 is entered
cin >> tester;
} while (tester < 1 || tester > 9);
// Put initial value into test Vector
if (theCheckening(testCaseOut, tester)){ // If check function returns true, add value to row 1
loShu1.push_back(tester);
testCaseOut.push_back(tester);
cout << "It worked?!";
}
} while (loShu1.size() <= 2); // shooting for size of 3, working as intended
for (int var : loShu1) // Debug to see rows before maths and adding them (to come)
cout << var << " ";
cout << "\n";
for (int var : loShu2)
cout << var << " ";
cout << "\n";
for (int var : loShu3)
cout << var << " ";
return 0;
}
bool theCheckening(vector<int> testCaseInc, int testInt) {
int count;
vector<int> testCase(testCaseInc); // Initialize vector inside check function to current test numbers
for (int var : testCase)
cout << var << " ";
for (count = 0;count<=testCase.size();count++) { // for all the numbers inside the testing vector
if (testCase[count]!=testInt){ // if current position of test vector is ! in vector already,
cout << "ADDED!"; // add it to row back in main()
return true;
for (int var : testCase)
cout << var << " ";
}
cout << "ALREADY ENTERED!"; // Debug
cout << testCase.size();
return false; // otherwise, ignore and ask for another number
}
}

i think you have a logical error in your theCheckening function.
As far as i understand you want your function to return TRUE if the value is NOT in in the vector and FALSE if it IS in your vector.
Now to the problem:
Imagine someone has tipped in the following values to your code:
1 2 5 8
This values will be added to your vector and the vector will also contain:
1 2 5 8
Now let's say you tipp one more time the 2. Your Function will now start with value 1 of the vector and compare it to the 2. This is of course FALSE.
Look at your code:
if (testCase[count]!=testInt)
return true;
Your code says you can now return true. Which will cause your function to end and return true to the caller.
You didn't check the following values of the vector.
Your function theCheckening should look like this:
// user const vector<int> &, which will not cause to copy the
// vector
bool theCheckening(const vector<int> & testCase, int testInt) {
// use size_t which represents a integer datatype which
// is as big as arrays can be in the current bit setting
// 32 bit => size_t = unsigned int
// 64 bit => size_t = unsigned long long
for(size_t count = 0; count <= testCase.size(); count++) {
if(testCase[i] == testInt)
return false;
}
return true;
}
I hope this works and i understood this qestion correctly.

Related

Not getting correct output Function not working

I'm trying to write a code that will take a number that the user inputted and create an inverted triangle like:
8 6 4 2 0 on the first line,
6 4 2 0 on the second line,
4 2 0 on the third line,
2 0 on the fourth line,
0 on the last line.
My nested for loops worked in a previous code that was in the main not in a function, but I decided I wanted to create a function that when called would run through the loops. However, something in my code isn't right since now I don't get an inverted triangle. I just get 0 and I think that's because my return is 0. I'm not sure if I'm writing my function incorrectly or if it's something else.
Please help. Thank you
#include <iostream>
using namespace std;
int row(int num)
{
int number;
int decreasedNumber;
for(int i = number; i >= 0; i -= 2)
{
decreasedNumber = i;
for(int j = decreasedNumber; decreasedNumber >= 0; decreasedNumber -=2)
{
cout << decreasedNumber << " ";
}
cout << endl;
}
return 0;
}
int main()
{
int number;
//Prompting the user to enter a number and collect that input
cout << "Enter a number: " << endl;
cin >> number;
cout << row(number);
return 0;
}
You are accepting num as a parameter to row, but never using it. Also, you are using number, but never initializing it. Instead, it seems you want number to be the parameter to the function, instead of a local variable.
Here's a demo.
Also, the variable j is never used in the loop, so you should just remove it.
Also, please don't use using namespace std;, it's a bad habit that you should avoid.
You are using number as the initial value of i.
number is uninitialized and its value is indeterminate.
Instead of number, you should use the argument num as the initial value of i.

Why does my function not switch the first character with the last one of my string?

I picked up a challenge on r/dailyprogrammer on reddit which wants me to match a necklace and put the last letter at the beginning of a string. I've considered using nested for loops for this but this has made me really confused.
Instead I chose the way of replacing the last with the first character in an if-statement. But I am not getting my desired output with it, though I've tried everything what comes into my mind.
I used even std::swap() which didn't lead me to success either.
Here's the code:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string same_necklace(string& sInput, string& sOutput)
{
for (string::size_type i = 0; i < sInput.size(); i++)
{
if (sInput[i] == sInput.size())
{
sInput[0] = sInput[sInput.size()];
}
}
for (string::size_type j = 0; j < sOutput.size(); j++)
{
if (sOutput[j] == sOutput.size() - 1)
{
sOutput[0] = sOutput[sOutput.size()];
}
}
return sInput, sOutput;
}
int main()
{
system("color 2");
string sName{ "" };
string sExpectedOutput{ "" };
cout << "Enter a name: ";
cin >> sName;
cout << "Enter expected output: ";
cin >> sExpectedOutput;
cout << "Result: " << same_necklace(sName , sExpectedOutput) << endl;
return 0;
}
And of course the link to my challenge (don't worry, it's just Reddit!):
https://www.reddit.com/r/dailyprogrammer/comments/ffxabb/20200309_challenge_383_easy_necklace_matching/
While I am waiting (hopefully) for a nice response, I will keep on trying to solve my problem.
In your if you compare the value of the current index (inside the loop) with the size of the string. Those are two unrelated things.
Also, you use a loop though you only want to do something on a single, previously known index.
for (string::size_type i = 0; i < sInput.size(); i++)
{
if (sInput[i] == sInput.size())
{
sInput[0] = sInput[sInput.size()];
}
}
You could change the if condition like this to achieve your goal:
if (i == sInput.size()-1) /* size as the index is one too high to be legal */
But what is sufficient and more elegant is to drop the if and the loop. completely
/* no loop for (string::size_type i = 0; i < sInput.size(); i++)
{ */
/* no if (sInput[i] == sInput.size())
{*/
sInput[0] = sInput[sInput.size()-1]; /* fix the index*/
/* }
} */
I.e.
sInput[0] = sInput[sInput.size()-1]; /* fix the index*/
Same for he output, though you got the correct index already correct there.
This is not intended to solve the challenge which you linked externally,
if you want that you need to describe the challenge completely and directly here.
I.e. this only fixes your code, according to the desription you provide here in the body of your question,
"put the last letter at the beginning of a string".
It does not "switch" or swap first and last. If you want that please find the code you recently wrote (surely, during your quest for learning programming) which swaps the value of two variables. Adapt that code to the two indexes (first and last, 0 and size-1) and it will do the swapping.
So much for the loops and ifs, but there is more wrong in your code.
This
return sInput, sOutput;
does not do what you expect. Read up on the , operator, the comma-operator.
Its result is the second of the two expressions, while the first one is only valuated for side effects.
This means that this
cout << "Result: " << same_necklace(sName , sExpectedOutput) << endl;
will only output the modified sExpectedOutput.
If you want to output both, the modified input and the modified output, then you can simply
cout << "Result: " << sName << " " << sExpectedOutput << endl;
because both have been given as reference to the function and hence both contain the changes the function made.
This also might not answer the challenge, but it explains your misunderstandings and you will be able to adapt to the challenge now.
You have not understand the problem i guess.
Here you need to compare two strings that can be made from neckless characters.
Lets say you have neckless four latters word is nose.
Combination is possible
1)nose
2)osen
3)seno
4)enos
your function (same_necklace) should be able to tell that these strings are belongs to same necklace
if you give any two strings as inputs to your function same_necklace
your function should return true.
if you give one input string from above group and second input string from other random word thats not belongs to above group, your function should return false.
In that sense, you just take your first string as neckless string and compare other string with all possible combination of first string.
just move move you first latter of first input string to end and then compare each resulting string to second input string.
below is the function which you can use
void swap_character(string &test)
{
int length = test.length();
test.insert(length, 1, test[0]);
test.erase(0, 1);
}

i'm having trouble with a while-loop that I just can't figure out why it won't work as desired

Made a while-loop and I'm not getting the result I think I should be getting.
I've done a little debugging and got nothing. Visual Studio 2019 is saying I'm good to go.
int main()
{
double num_enter;
vector<double> nums(0);
while (cin >> num_enter)
{
nums.push_back(num_enter);
sort(nums.begin(), nums.end());
if (num_enter < nums.front())
{
cout << num_enter << " is the smallest one yet.\n" << endl;
}
else if (num_enter > nums.back())
{
cout << num_enter << " is the biggest one yet.\n" << endl;
}
return 0;
}
I want a while(cin>>enter_num) loop to read num_enter and do a vector.push_back(num_enter) followed by the vector sort function and have it out put if the number has been "the smallest yet" or "the biggest yet" but its not working. could you point out what I'm doing wrong? I'm new be gental.
There is only one number in the vector. None of the conditions are met, if you enter one, one is not greater than one or less than one, hence it is not printing anything because you are not handling that case. Add an else block that prints if the numbers are equal then hopefully it will be clear to you why that is happening.
try this
// Example program
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
double num_enter;
vector<double> nums(0);
while (cin >> num_enter) {
nums.push_back(num_enter);
//sort(nums.begin(), nums.end());
// Lets say you entered 1
// 1 < 1 -> false
if (num_enter < nums.front())
{
cout << num_enter << " is the smallest one yet.\n" << endl;
}
// 1 > 1 -> false
else if (num_enter > nums.back())
{
cout << num_enter << " is the biggest one yet.\n" << endl;
}
else // 1 == 1
{
cout << "Numbers are equal" << endl;
}
return 0;
}
}
Syntax of vector:
vector vectorName(size);
vector nums(0)
In your code nums is a vector of size zero.
Vector is a dynamic array.
Array of zero size is meaningless.
Check this link to see different ways of declaring vector.
suppose you code order should be changed, the if-elseif-else block should be put in front of the push_back and sort,
or if you really want to maintain the order, if-elseif-else should be corrected like if(num_enter == nums.front()) ... else if(num_enter == nums.back())... else,
only then you can know if your input number has been the biggest or smallest yet.
And initialize like vector<double>nums(0) is little weird, just using vector<double>nums is fine

how to convert an for loop to while loop c++

I'm trying to convert a for loop to while loop in c++ and do some checking for duplicates in a random number generator for generating lotto numbers so far all the stuff i'm trying seems to make the compiler very unhappy and I could really use a few pointers. It's the for loop in the Harray() function that feeds the Balls[] array
that i want to convert to a while loop.
#include<iostream>
#include<cstdlib> // to call rand and srand.
#include<ctime> // to make rand a bit more random with srand(time(0)) as first call.
#include<iomanip> // to manipulate the output with leading 0 where neccesary.
using namespace std;
// Hrand() function create and return a random number.
int Hrand()
{
int num = rand()%45+1; // make and store a random number change 45 for more or less Balls.
return num; // return the random number.
}
// Harray() function create and fill an array with random numbers and some formatting.
void Harray()
{
int Balls[6]; // change the number in Balls[6] and in the for loop for more or less nrs. a row.
for(int x=0; x<=6; x++) //the loop to fill array with random numbers.
{
int a; // made to pass the Balls[x] data into so i can format output.
int m = Hrand(); // calling the Hrand() function and passing it's value in int m.
Balls[x] = m; // throwing it into the array tought i did this because of an error.
a = Balls[x]; // throwing it into int a because of an type error.
cout<<"["<<setfill('0')<<setw(02)<<a<<"]"; //format output with leading 0 if neccesary.
}
cout<<endl; // start new row on new line.
}
// Main function do the thing if compiler swallows the junk.
int main() // start the program.
{
int h; // int to store user cchoice.
srand(time(0)); // make rand more random.
cout<<"How many rows do you want to generate?"<<endl; // ask how many rows?
cin>>h; // store user input.
for(int i=h; h>0; h--) // produce rows from user input choice.
{
Harray(); // calling Harray function into action.
}
return 0; // return zero keep the comipler happy.
}
I would like to always have six diffrent numbers in a row but i don't see how to get there with the for loops i think the while loop is way to go but am open to any suggestion that will work. I'm just starting with c++ i might have overlooked some options.
int x=0;
while(x<6)
{
int a;format output.
int m = Hrand();value in int m.
Balls[x] = m; because of an error.
a = Balls[x];
cout<<"["<<setfill('0')<<setw(02)<<a<<"]";
x++;
}
Here, I also fixed a bug. Since Balls has 6 elements, the last element will be 5. Thus you want x<6 instead of x<=6. That goes for the for loop too.
One drawback of while loops is that you cannot declare local variables with them.
First of all, you should realize that the difference between a for loop and a while loop is mostly syntactic--anything you can do with one, you can also do with the other.
In this case, given what you've stated as your desired output, what you probably really want is something like this:
std::vector<int> numbers;
std::set<int> dupe_tracker;
while (dupe_tracker.size() < 6) {
int i = Hrand();
if (dupe_tracker.insert(i).second)
numbers.push_back(i);
}
The basic idea here is that dupe_tracker keeps a copy of each number you've generated. So, you generate a number, and insert it into the set. That will fail (and return false in retval.second) if the number is already in the set. So, we only add the number to the result vector if it was not already in the set (i.e., if it's unique).
How convert for-loop to while-loop
#include <iostream>
class T545_t
{
// private data attributes
int j;
public:
int exec()
{
// A for-loop has 3 parameters, authors often fill 2 of them with magic
// numbers. (magic numbers are usually discouraged, but are expected
// in for-loops)
// Here, I create names for these 3 for-loop parameters
const int StartNum = 2;
const int EndNum = 7;
const int StrideNum = 2;
std::cout << std::endl << " ";
for (int i = StartNum; i < EndNum; i += StrideNum ) {
std::cout << i << " " << std::flush;
}
std::cout << std::flush;
// A while-loop must use / provide each of these 3 items also, but
// because of the increased code-layout flexibility (compared to
// for-loop), the use of magic numbers should be discouraged.
std::cout << std::endl << " ";
j = StartNum;
do {
if (j >= EndNum) break;
std::cout << j << " " << std::flush;
j += StrideNum;
} while(true);
std::cout << std::flush;
std::cout << std::endl << " ";
j = StartNum;
while(true) {
if (j >= EndNum) break;
std::cout << j << " " << std::flush;
j += StrideNum;
}
std::cout << std::flush;
std::cout << std::endl << " ";
j = StartNum;
while(j < EndNum) {
std::cout << j << " " << std::flush;
j += StrideNum;
}
std::cout << std::endl;
return 0;
}
}; // class T545_t
int main(int , char** )
{
T545_t t545;
return(t545.exec());
}
Ask me where 'j' is declared?
This code is marked as C++, so in this case, I have declared 'j' in the private data attribute 'section' of this class definition. That is where you'd look for it, right?
If your c++ code does not have class, what's the point?

My bool function keeps returning true and im not sure why

Im doing an excercise sheet to get an understanding of functions and I am currently working on the following question.
Write function prototypes for each of the following:
A function HasValue that may be passed a reference to an array, the size of the array and a
search value. The function should return true if the search value exists in the array
In my code I have sent the contents of the array, the array size and the value to be searched in the array to the bool function.
In the function I compared the value to each element of the array using a for loop.
I then created a variable count in the function that will be incremented if the value matches any element in the array.
I then used an if else statment to return true if count is greater than 0 and false if count is equal to 0. The problem is however that the function is only returning true thus the output will always be "this number appears in the array"
Logically these steps seem correct to me but obviously there is a flaw somewhere that I cant see. I presume its just I do not have a decent understanding of Bool functions yet but if someone could explain where and why I'm going wrong it would be greatly appreciated in my learning process to understanding functions and c++.
#include <iostream>
#include <iomanip>
#include "stdafx.h"
using namespace std;
bool HasValue(int Array[], int size, int Value);
int main()
{
int value;
int Array[10]{ 3,5,6,8,9,1,2,14,12,43 };
cout << "enter value you wish to search for in array " << endl;
cin >> value;
HasValue(Array, 10 , value);
if (true)
cout << "This number appears in the array " << endl;
else
cout << "This number does not appear in the array " << endl;
return 0;
}
bool HasValue(int Array[], int size, int Value)
{
int count = 0;
for (int i = 0; i < size; i++)
{
if (Value == Array[i])
{
count++;
}
}
if (count > 0)
{
return true;
}
else
return false;
}
You test code is the problem
HasValue(Array, 10 , value);
if (true)
cout << "This number appears in the array " << endl;
else
cout << "This number does not appear in the array " << endl;
This ignores the return value of HasValue and always prints "This number appears in the array".
HasValue(Array, 10 , value);
This line of code executes the function but ignores the returned value. When a function returns a value, you need to assign it to a variable:
bool result = HasValue(Array, 10 , value);
Then if (true) does not have any reference to the returned value. The true inside the if will cause the first cout to always print. You will never see the output from the else. But once you have the return value in a variable, you can use it in the if:
if(result)
You can reduce this all to one line of code, if you want:
if(HasValue(Array, 10 , value))
Now the if statement will directly test the return value from HasValue(). In this particular case, combining the code into a single line seems reasonable. You must be careful doing this, though. When you combine too much into a single line, the code becomes more difficult to debug. You will need to find a balance between readability and convenience as you continue learning how to program.