“invalid operands to binary expression” error? - c++

C++ newbie here, basically I am trying to print out a list of random characters based off user input. I know my error involves the "m <= num" statement, but not sure how to go about fixing that. Or am I going about this completely wrong? Explanations are greatly appreciated!
Note My logic is that 'm' is the list of characters so for 'num' I am trying to print out a list of characters based on the value of 'num'. For example if the user selects 2 for list and 5 for elements I would want the output to be....
list 1: "wtwef"
list 2: "wopoe"
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
int main() {
srand (time(NULL));
int L;
string alpha = "abcdefghijklmnopqrstuvwxyz";
list<string> m;
cout << "Give the number of lists: ";
cin >> L;
for (int i = 1; i <= L; i++){
cout << "Give the number of elements for list " << L << " : "<< endl;
int num; cin >> num;
for (int k = 0; m <= num; k++){
cout << alpha[rand() %100] << " " << endl;
m.push_back(alpha[rand() %100]);
}
cout << "Give a word: " << endl;
cin >> s;
}

The issue with the expression "m <= num" is because m is of type std::list while num is of type int. It doesn't make sense to compare a list with an int, which is the real world equivalent of comparing a shopping list with 4, it just doesn't mean anything. You may have intended "k <= num".
The line cin >> s is also an error, s isn't defined.
You also have a line m.push_back(alpha[rand() % 100]); that will be an error, m has a type of string while the using the [] operator on alpha will return a character, see code below for solution.
You use the modulus operator in two places, where you mod by 100. If you want a character at a random index you should, in this case, do alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1). Note that RAND_MAX is a constant that should be predefined, you shouldn't need to set it. I have a feeling what you're trying to accomplish in the inner loop looks like:
string randomCharacter = alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1)
cout << randomCharacter << " " << endl;
m.push_back(randomCharacter);
You are also missing a left brace in the code somewhere (may be due to copy-paste) which would be another reason it wouldn't compile.
If what you want is to be able to type in the terminal how many sequences of random characters followed by how many characters are in each sequence, you would want to re-write the inner loop to look like:
string randomCharacters = "";
for (int k = 0; k <= num; k++){
string randomLetter = alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1);
cout << randomLetter << " " << endl;
randomCharacters += randomLetter;
}
m.push_back(randomCharacters);
This will fill the list with strings filled with random characters from array alpha, which you can use later. You can remove the cout if you don't want to see all the characters printed to the terminal as they are randomly chosen.
After your edit to the question:
The solution should look like:
srand(time(NULL));
int L;
string alpha = "abcdefghijklmnopqrstuvwxyz";
vector<string> m;
cout << "Give the number of lists: ";
cin >> L;
cout << "Give the number of elements for the lists: ";
int num;
cin >> num;
cout << endl;
for (int i = 1; i <= L; i++){
string randomCharacters = "";
for (int k = 0; k < num; k++){
string randomLetter = alpha.substr((double) rand() / RAND_MAX * alpha.length(), 1);
randomCharacters += randomLetter;
}
m.push_back(randomCharacters);
}
for(int i = 0; i < m.size(); i++)
{
cout << "list" << (i+1)<< ": " << m[i] << endl;
}
Note, this solution switched list for vector as it's simpler in this case.

Related

How can i prohibit duplicate input values on a 2D array?

Here is my code and I want to restrict reoccurring values when the user is trying to input the same value. It would be best if everything is only at the main function because i'm still learning about declaring more functions.
`
#include <iostream>
using namespace std;
int main() {
int num[10][10];
int times;
cout << "Please input the number of times you wish to enter a value but does not exceed to 100: ";
cin >> times;
cout << "Enter a value " << times * times << " times." << endl;
for(int i = 0; i < times; i++) {
for(int k = 0; k < times; k++) {
cout << "Please input a number on index [" << i << "][" << k << "]: ";
cin >> num[i][k];
}
}
//Displaying the inputs
cout << "Printing all values inside the array: " << endl;
for(int i = 0; i < times; i++) {
cout << endl;
for(int k = 0; k < times; k++) {
cout << "\t" << num[i][k] << " ";
}
}
return 0;
}
`
This is my expected output to be when a user tries to input a duplicate value:
Please input a number on index [0][0]: 7
Please input a number on index [0][1]: 7
Value already entered. Please try again.
Please input a number on index [0][1]:
In this context, you could have a function like this:
bool doesExist(
const int array[][10], const size_t size, const int value, int x, int y)
{
for (size_t i = 0; i < size; i++)
for (size_t j = 0; j < size; j++) {
if (x == i && y == j)
continue; // Skip the new element.
// If duplicate found
if (value == array[i][j])
return true;
}
return false;
}
It takes the array, its size, the value to be compared, and the position of the unique element inserted for the first time as arguments.
You could implement it this way:
cin >> num[i][k];
if (doesExist(num, times, num[i][k], i, k)) {
cout << "Already exists.\n";
...
}
This is not the best approach to this problem. In C++, it is recommended to apply STL containers as they provide more safety and iterators.
You just want the use not to enter duplicate values :-
First very basic you can just check all the previous values,
if it matches with the current one then you can tell the user to change the value.
You can use unordered_map, as map is (key,value) pair whenever you insert any value in map just set its corresponding value to 1, and then you can check in your map if thats value is already present in map or not if its present then you can tell the user to change, in map it will be easy to search.(code is simple)

C++: Removing a duplicate of the user input in an array

I have been trying to solve this problem since yesterday. The program should accept N numbers from the user and will place them in an array. I have done this. However, I don't seem to know how to "warn" the user that the input is a duplicate and lets the user enter again.
Here is my code:
# include <iostream>
using namespace std;
int main () {
int N, pos = -1, arr [N], i, j;
int startLoop = 1;
// the 'startLoop' variable is used so that the first user input can have the break function
bool found = false;
while (startLoop != 0) {
cout << "Enter the number of integers to be entered: ";
cin >> N;
if (N <= 4) {
cout << "Invalid. \n";
}
if (N > 4) {
cout << "\n\nEnter " << N << " unique numbers: " ;
for (i = 0; i < N; i++) {
cin >> arr [i];
for (j = 0; j < N && !found; j++) {
if (arr [j] == arr [i]) {
found = true;
cout << "Enter again: ";
}
}
break;
}
}
}
The following is the copy paste of your code:
By adding break you will jump out of the outer for loop and you cannot read n inputs.
the inner loop range is not correct since i is the total number of values read by now. i.e. if N= 10 and in third iteration you are trying to loop among 10 elements to double check if the latest number is a duplicate, while you have read 3 elements by now.
if (N > 4) {
cout << "\n\nEnter " << N << " unique numbers: " ;
for (i = 0; i < N; i++) {
cin >> arr [i];
for (j = 0; j < N && !found; j++) {
if (arr [j] == arr [i]) {
found = true;
cout << "Enter again: ";
}
}
break;
}
}
How to fix?
One approach would be to read the input in a separate loop and then try to find the duplicates and remove them.
Time Complexity will be O(n) since you need to traverse through the list twice, however you need to implement removing elements from the array efficiently without shifting all the elements
Second approach is like what you are trying to implement but it is not efficient since every time a user is adding a new elements you need to re-evaluate i numbers (in worst case n numbers when you are filling the end of array). this process should be repeated every time user insert a repeated number.
The best approach would be store all input numbers inside a hash (set) and every-time a new number is inserted check whether it is already suggested by the user or not. Time complexity of searching elements through unordered_set will be O(1)
Problems:
Your code has many several problems:
You shouldn't use VLAs (Variable Length Arrays) as they are non-standard.
Using N before initializing it is UB (Undefined Behaviour).
Your approach is not efficient as it checks on average n/2 elements n times and therefore it has a time complexity of O(n^2).
You have many unused variables and variables that should be in a more specific scope.
Solutions:
Use std::vector insted of VLAs.
Resize the vector after initializing N.
Change your approach.
Change the scope of your variables.
Additional information:
using namespace std; is considered a bad practice (More info here).
You should probably add input checking to std::cin to verify that the input is a number.
Full code:
Checking duplicates once at the end of input with std::vector (Time complexity: O(n * log(n)). Space complexity: O(n)):
#include <iostream>
#include <vector>
#include <algorithm>
bool hasDuplicates(std::vector<int> toCheck)
{
std::sort(toCheck.begin(),toCheck.end());
for(unsigned int i = 1; i < toCheck.size(); i++)
if(toCheck[i] == toCheck[i-1])
return true;
return false;
}
int main () {
std::vector<int> arr;
int N;
while (true) {
std::cout << "Enter the number of integers to be entered: ";
std::cin >> N;
if (N <= 4) {
std::cout << "Invalid: The number of integers to be entered must be bigger than 4. \n";
}
else {
arr.resize(N);
std::cout << "\n\nEnter " << N << " unique numbers: " ;
for (int i = 0; i < N; i++)
std::cin >> arr [i];
if(hasDuplicates(arr))
std::cout << "Invalid: The numbers must be unique. \n";
else
break;
}
}
}
Checking duplicates each time a number is entered with std::unordered_map (Time complexity: Amortized O(n). Space complexity: O(n)):
#include <iostream>
#include <vector>
#include <unordered_set>
int main () {
std::vector<int> arr;
std::unordered_set<int> alreadyAppeared;
int N;
std::cout << "Enter the number of integers to be entered: ";
std::cin >> N;
while (N <= 4) {
std::cout << "Invalid: The number of integers to be entered must be bigger than 4. \n";
std::cout << "Enter the number of integers to be entered: ";
std::cin >> N;
}
arr.resize(N);
std::cout << "\n\nEnter " << N << " unique numbers: \n";
for (int i = 0; i < N; i++)
{
int entering;
std::cout << "Enter unique number: ";
std::cin >> entering;
if(alreadyAppeared.find(entering) == alreadyAppeared.end())
{
alreadyAppeared.insert(entering);
arr[i] = entering;
}
else
{
std::cout << "Invalid: The numbers must be unique. \n";
i--;
}
}
}

How to count by three from the number given by the user?

I have to create a program using a for loop that will count by 3 from the given number from the user 20 times. So far this is what i have.
#include <iostream>
using namespace std;
int main(){
int num, newNum, add;
cout << "Enter a number: ";
cin >> num;
for(int count = 0; count < 20; count++){
for(int sum = 0; sum <= count; sum++){
newNum = num * (count +1);
}
cout << num << " ";
}
}
I have no idea where to go from here. I know that i would have to put the number given into a variable like i do with num and i know i would somehow have to store the new number in another variable like i do with newNum. Any help would be appreciated! Also this is what the output should look like in case i did not explain it good enough.
Enter a number: 3
3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60.
And bonus points if you can have the last number end with a period instead of a comma :)
This should work:
int main(){
int num, currentNum, add, newNum;
std::cout << "Enter a number: ";
std::cin >> num;
std::cout << num
for(int count = 0; count < 20; count++){
num += 3;
std::cout << ", " << num;
}
std::cout << " ." << std::endl;
}
Also try to not use using namespace std. It clutters the namespace.
You can add 3 to the number either inside the loop's third statement (you can also have multiple conditions etc.)
for(int count = 0; count <= 20; count++, num+=3){
// ...
}
or inside the loop's code block
for(int count = 0; count <= 20; count++){
num += 3;
}
As for the comma you just need to add it to the output:
cout << num << ", ";
Since you want a dot at the end you need to handle this in an if-else case
if (count < 20)
cout << num << ", ";
else
cout << num << ".";
or a ternary operator:
cout << num << (num < 20) ? ", " : ".";
Bonus points: don't expose the complete namespace (here: std). While in such a small example it's not an issue it may lead to hard to detect bugs later on if you happen to use one or multiple namespaces that offer the same functionality.
OK, we have so far an answer explaining pretty well and another one optimising the if inside the loop away. We still can optimise away one addition, if you count up the num variable directly:
for(auto end = num + 57; num < end; num += 3)
// ^ still one number less, last one follows the loop!
{
std::cout << num << ", ";
}
std::cout << num << '.' << std::endl;
// ^ ^ not much difference, but just outputting a single character
// is more efficient, no need to iterate to find the
// trailing null character...
std::endl not only adds a newline, but flushes the stream immediately (i. e. the so far possibly buffered output is forced to be printed to console). This is especially useful if there's more output to follow, but possibly quite a while later (without flushing, user might see incomplete last line). Admitted, in given case not necessary, as std::cout's destructor will flush anyway, so you could go, too, with the slightly simpler std::cout << num << ".\n"...
Without using the extra variables.
#include
using namespace std;
int main(){
int num, currentNum, add, newNum;
cout << "Enter a nummber: ";
cin >> num;
for(int count = 0; count <= 20; count++){
cout << (num + count * 3);
if(count == 20)cout<<".\n";
else cout<<", ";
}
}
More general solution would be:
#include <iostream>
using namespace std;
int main(){
int num, currentNum, add;
cout << "Enter a nummber: ";
cin >> num;
add = 3;
currentNum = num;
for(int count = 0; count <= 20; count++){
cout << (currentNum); //Print current number
currentNum = currentNum + add; // increase the number
if(count == 20)cout<<".\n"; //if the last one print dot
else cout<<", "; //else place comma
}
}

Print number of matching sequence in the user given input for the constant input

I wrote a code to get the number of sequences occurring in the user input sequence.
This is my code. It excludes the subsequence which I wish to be tested.
I need to consider 12,23,34,123,234,1234 as sequences.
Overlapping of sequences should not be considered (12 in 123 should not be considered).
For e.g. constant number 1234
User given number 124312341211423
Output : No.of Sequence found 4
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int main()
{
string num1;
string seq;
cout << "Enter constant number: ";
cin >> num1;
cout << "Enter the sequence: ";
cin >> seq;
int count=0;
for (int t=0; t<=num1.size()-2; t++)
{
string num = num1;
for (int k = num1.size(); k>=2-t ;k--)
{
cout << num <<"\n";
if (t==2 && k<=2)
break;
//num=num.substr(t,t+k-1);
for (int j = 1; seq.find(num) != string::npos; j++)
{
seq = seq.substr(0,seq.find(num)) + " " + seq.substr(seq.find(num)+num.size());
count = count + 1;
}
num = num.substr(t,t+k-1);
}
cout<< seq << "\n";
}
cout << "No. of sequences found: " << count << "\n";
return 0;
}
Hi I tried running your code and I got it outputting 5 sequences found. I'm assuming your request is to figure out why it's not 4.
I'll make a couple recommendations:
The logic of your for-loops and forming num should be adjusted to test all substrings of num1 such that each substring is at least 2 characters in length.
Change your most-interior for-loop into a while loop, because your iterator j really isn't doing anything.
Call string::find() once per iteration of your most-interior loop. String::find() is expensive and you call it three times without changing the arguments.
Pull the declaration of num out of the for-loop so it's only declared once.
Here is the result of these recommendations in effect:
You'll notice I added a variable numStart to save the location of the beginning of num in seq, thus allowing recommendation #3 to be done.
I also moved cout << seq << "\n" into the most-interior loop so you can see the state of seq every time a sequence is found.
int main() {
string num1;
string num;
string seq;
cout << "Enter constant number: ";
cin >> num1;
cout << "Enter the sequence: ";
cin >> seq;
int count=0;
for (int t=0; t<=num1.size(); t++) {
for (int k = num1.size(); k>t+1; k--) {
num = num1.substr(t, k-t);
size_t numStart = seq.find(num);
while (numStart != string::npos) {
seq = seq.substr(0, numStart) + " " + seq.substr(numStart + num.size());
count++;
numStart = seq.find(num);
cout << seq << "\n";
}
}
}
cout << "No. of sequences found: " << count << "\n";
return 0;
}
I hope this helps!

Adding consecutive integers from an input (Translated from Python to C++)

I'd like to request some help on my HW. I think I'm really close to figuring this out. Our CompSci class is currently shifting from learning Python to (introductory) C++. Since the two are vaguely similar, we've been advised, since we're beginners, to code the problem in Python (which we're very familiar with) and to translate it into C++ using the basics we just learned. The problem to solve is a simple "add the consecutive integers from 1 to that number, given a positive integer input." So an example would be:
>>Enter a positive integer: 10
>>1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55
The Python code (this was successful) that I'm attempting to translate into C++ is:
num = int(raw_input("Enter a positive integer: "))
sum = 0
for i in range(1, num):
sum += i
print i, "+",
print num, "=", sum+num
And my unsuccessful C++ code:
#include <iostream>
using namespace std;
int main()
{
int num;
int sum;
int i;
sum = 0;
cout << "Please enter a positive integer: " << endl;
cin >> num;
for (i=0; 1 <= num; i++)
{
sum = sum + i;
cout << i << "+" << endl;
}
cout << num << "=" << sum + num << endl;
return 0;
}
But the output is simply an infinite, non-ending addition sequence from 0 to infinity, going top to bottom. Even worse is that it did not print in a straight line like I want it. As you can see, I quite literally tried to translate it word-for-word; I thought that'd be foolproof. Something must be wrong with my for loop. Since C++ doesn't have a class of its own for "range" like Python does, I thought the middle condition statement ("1 <= num;") would act as the range. Why didn't my "=" sign print out? And I don't understand why it won't terminate when it reaches "num." Think you can help? I thank you in advance for the replies.
Fixed code:
#include <iostream>
using namespace std;
int main()
{
int num;
int sum;
int i;
sum = 0;
cout << "Please enter a positive integer: " << endl;
cin >> num;
// Here you had 1 <= num which was always true for positive num
// and it did not depend on value of i.
for (i = 1; i < num; ++i)
{
sum = sum + i;
cout << i << "+"; // Here you had endl which produced newline characters.
}
cout << num << "=" << sum + num << endl;-
return 0;
}
This:
for (i=0; 1 <= num; i++)
should be:
for (i=0; i <= num; i++)
try this.
#include <iostream>
using namespace std;
int main()
{
int num;
int sum;
int i;
sum = 0;
cout << "Please enter a positive integer: ";
cin >> num;
for (i=0; i < num; i++)
{
sum = sum + i;
cout << i << " + ";
}
cout <<num << " = " << sum+num << endl;
return 0;
}
I don't really know Python, but the code
for i in range(1, num):
looks really similar to
for (int i=1; i <= num; ++i)
or is it possibly
for (int i=1; i != num; ++i)
which looks more like C++?
loop in c++ are most basic than python, the for loop is more simpler, it is based on the three expression: initializer expression, the loop test expression, and the counting expression. In particular what is wrong in your code is the test expression. Remember that the loop is executed if the test expression is true. You need to loop if the condition i<num is true. Your loop is never ending because num is always >= 1, or as you wrote 1 <= num always.
To print everythig on a line don't use endl