Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to store 5 integers into a string, but I am having trouble. Here is the code:
for (int a = 0; a < 5; a++)
{
string ans;
int number;
int num;
number = rand() % 9 + 1;
cout << number << " ";
num = number;
to_string(num);
ans =+ num;
}
Essentially, I would like "ans" to be something along the lines of "12345" but when I run it, it either doesn't show anything or shows 5 boxes with question marks inside of them. Any help?
You can do something like this:
string ans;
int number;
for (int a = 0; a < 5; a++){
number = rand() % 9 + 1;
ans += to_string(number);
}
cout << ans;
to_string() returns a string.
You can simply try doing:
ans += to_string(num);
Or, better way to write your code for improved readability is to use a temporary string variable instead of an int num to store the number.
string temp;
string ans;
for (int a = 0; a < 5; a++)
{
//string ans;
int number;
//int num;
number = rand() % 9 + 1;
cout << number << " ";
//num = number;
temp = to_string(number);
ans += temp;
}
You do not want to declare your string ans inside the for loop because every time the loop runs, you ans will not hold the previous value anymore as it gets declared again.
There are a number of problems with your code.
you are declaring ans inside the loop, so it is created and destroyed on each loop iteration. If you want the loop to append 5 numbers to ans, you have to declare it outside of the loop instead.
std::to_string() outputs a new std::string as its return value. It does not "magically" turn the input value into a string type, like your code is assuming. You are not appending the returned string to ans at all.
=+ is not a valid append operator. It is interpreted as separate operators = and +. std::string does not have a = operator that takes an int as input, and does not have a unary + operator. You need to use the += operator instead.
Try this:
#include <string>
#include <iostream>
std::string ans;
for (int a = 0; a < 5; ++a)
{
int number = ...
...
ans += std::to_string(number);
}
// use ans as needed...
Alternatively, use std::ostringstream instead of std::to_string():
#include <string>
#include <sstream>
#include <iostream>
std::ostringstream oss;
for (int a = 0; a < 5; ++a)
{
int number = ...
...
oss << number;
}
std::string ans = oss.str();
// use ans as needed...
With that said, you are clearly using C++11 (when std::to_string() was introduced) or later, so you should be using a C++ random number generator instead of the one from C, eg:
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 9);
for (int a = 0; a < 5; ++a)
{
int number = dis(gen);
...
}
Related
To find all sequences of fixed length which contain only 0 and 1 I use this code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void print_array(vector<string> arr) {
cout << '[';
int n = arr.size();
for (size_t i = 0; i < n; i++) {
cout << arr[i];
if (i < (n - 1)) {
cout << ", ";
}
}
cout << ']' << endl;
}
vector<string> get_variants(int n) {
vector<string> result = {"0", "1"};
vector<string> temp;
temp.reserve(2);
result.reserve(2);
for (int i=0; i < (n - 1); ++i) {
copy(result.begin(), result.end(), temp.end()); // [1]
for (int j=0; j < result.size(); ++j) {
temp[j] += "0";
result[j] += "1";
}
copy(temp.begin(),temp.end(), result.end());
temp.clear();
}
return result;
}
int main(int argc, char const *argv[]) {
int n;
cin >> n;
vector<string> maybe = get_variants(n);
print_array(maybe);
return 0;
}
But vector temp is empty, before copying in line which I marked [1] and after. So, my program's output was [0111, 1111]. What I'm doing wrong?
A more straightforward way than using std::copy is the use of .insert():
temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy
You are writing to temp.end() and result.end(). These iterators represent "one past the end", and therefore writing to these iterators is Undefined Behavior.
You seem to be looking for std::back_inserter. This will create an iterator that will insert a new element to your container when it is written through.
std::copy(result.begin(), result.end(), std::back_inserter(temp));
While this answers the posted question, there remain other errors in your code leading to Undefined Behavior.
Trying to compile your program with a C++ compiler will not work, because you include #include <bits/stdc++.h>which is a non tC++ standard compliant header.
You should never include this file.
You are using typical competitive programming stuff, but including all C++ headers and not use them will eat up Compile time for no good reason.
Then, you typedef the typical competitive programming abbreviations. 2 of them, you do not use. Then there is no reason to define them.
I recommend to not do this any longer. And in C++, please use the using statement.
Then, although you want to be fast, you pass arr by value to your print function. This will copy the whole vector.
You assign/compare a lot of int with unsigned int values. This you should not do.
Additionally: Please use meaningful variable names and write comments. The more the better.
Regarding your specific bug. Both std::copy statements use end iterator as target. End is end. It is past the end of the vector. Please use std::back_inserter instead.
Regarding the algorithm. I took a while for me to realize that you basically want to create binary numbers. Nothing else. Unfortunately you translated that in a very complicated way.
Normally, you just would count from 0 to 2^n-1 and then show the data. Thats all. Becuase the numbers may be of arbitraty length, we will use manual addition of digits like in scholl on a peice of paper. Very simple.
Everthing then biols down to some lines of code.
Please see:
#include <iostream>
#include <vector>
int main() {
// Read length of binary number to create and validate input
if (int numberOfDigits{}; (std::cin >> numberOfDigits and numberOfDigits > 0)) {
// Here we will store the binary digits, so 0s or 1s
std::vector<int> digits(numberOfDigits,0);
// Som printing helper
std::cout << '[';
bool printComma{};
// We need to print 2^n possible combinations
for (int i = 0; i < (1 << numberOfDigits); ++i) {
// Print comma, if need
if (printComma) std::cout << ','; printComma = true;
// Print all digits of the binary number
for (const int d : digits) std::cout << d;
// Calculate next binary number
int carry = 0;
for (int index=numberOfDigits -1; index >=0; --index) {
const int sum = digits[index] + ((index == (numberOfDigits - 1)?1:0)) + carry;
carry = sum / 2;
digits[index] = sum % 2;
}
}
std::cout << ']';
}
}
If there should be questions, then I am happy to answer.
This question already has answers here:
How to find the minimum number of operation(s) to make the string balanced?
(5 answers)
Closed 1 year ago.
I'm trying to write this program that asks for user input of string, my job is to print out the minimum number of steps required to equalize the frequency of distinct characters of the string.
Example
Input
6
aba
abba
abbc
abbbc
codedigger
codealittle
Output
1
0
1
2
2
3
Here is my program:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
int main()
{
unordered_map<char, int >m;
vector<int> vec1, vec2;
string s;
int n;
cin >> n;
cin.ignore();
for (int i = 0; i < n; ++i)
{
m.clear();
vec1.clear();
getline(cin, s);
for (int i = 0; i < s.size(); i++)
m[s[i]]++;
for (auto itr : m)
vec1.push_back(itr.second);
sort(vec1.begin(), vec1.end());
int mid = vec1[vec1.size() / 2];
int ans = 0;
for (auto itr : vec1)
ans += abs(mid - itr);
vec2.push_back(ans);
}
for (int i = 0; i < vec2.size(); ++i)
cout << vec2[i] << endl;
}
What I tried to do is for each test case:
Using an unordered_map to count the frequency of the characters of the string.
Push the key values of the map to a vector.
Sort the vector in ascending order.
Calculate the middle element of the vector to equalize the distinct characters with as least steps as possible.
The result will add the difference between the middle element with the current element.
Push the result to another vector and print it.
But my result is wrong at test case number 5:
1
0
1
2
3 // The actual result is 2
3
I don't understand why I get the wrong result, can anyone help me with this? Thanks for your help!
The issue is that your algorithm is not finding the optimal number of steps.
Consider the string you obtained an incorrect answer for: codedigger. It has 4 letters of frequency 1 (coir) and 3 letters of frequency 2 (ddeegg).
The optimal way is not to convert half the letters of frequency 2 into some new character (not present in the string) to make all frequency 1. From my understanding, your implementation is counting the number of steps that this would require.
Instead, consider this:
c[o]dedigge[r]
If I replace o with c and r with i, I obtain:
ccdediggei
which already has equalized character frequencies. You will note that I only performed 2 edits.
So without giving you a solution, I believe this might still answer your question? Perhaps with this in mind, you can come up with a different algorithm that is able to find the optimal number of edits.
Your code correctly measures the frequencies of each letter, as the important information.
But then, there were mainly two issues:
The main target value (final equalized frequency) is not necessarily equal to the median value. In particular, this value must divide the total number of letters
For a given targeted height value, your calculation of the number of steps is not correct. You must pay attention not to count twice the same mutation. Moreover, the general formula is different, depending the final number of different letters is equal, less or higher than the original number of letters.
The following code focuses on correctness, not on efficiency too much. It considers all the possible values of the targeted height (frequency), i.e. all the divisors of the total number of letters.
If efficiency is really a concern (not mentioned in the post), then for example one could consider that the best value is unlikely to be very far from the initial average frequency value.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <unordered_map>
// calculates the number of steps for a given target
// This code assumes that the frequencies are sorted in descending order.
int n_steps (std::vector<int>& freq, int target, int nchar) {
int sum = 0;
int n = freq.size();
int m = nchar/target; // new number of characters
int imax = std::min (n, m);
for (int i = 0; i < imax; ++i) {
sum += std::abs (freq[i] - target);
}
for (int i = imax; i < n; ++i) {
sum += freq[i];
}
if (m > n) sum += m-n;
sum /= 2;
return sum;
}
int main() {
std::unordered_map<char, int >m;
std::vector<int> vec1, vec2;
std::string s;
int n;
std::cin >> n;
std::cin.ignore();
for (int i = 0; i < n; ++i)
{
m.clear();
vec1.clear();
//getline(cin, s);
std::cin >> s;
for (int i = 0; i < s.size(); i++)
m[s[i]]++;
for (auto itr : m)
vec1.push_back(itr.second);
sort(vec1.begin(), vec1.end(), std::greater<int>());
int nchar = s.size();
int n_min_oper = nchar+1;
for (int target = 1; target <= nchar; ++target) {
if (nchar % target) continue;
int n_oper = n_steps (vec1, target, nchar);
if (n_oper < n_min_oper) n_min_oper = n_oper;
}
vec2.push_back(n_min_oper);
}
for (int i = 0; i < vec2.size(); ++i)
std::cout << vec2[i] << std::endl;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Something wrong with my code, I want to multiply a string of numbers with an array of numbers(same length) and store the product in variable product, then I want to store this product of each column in my string variable (as a new values)
string var1 = "1232253759";
int arr[] = {5,3,7,1,2,8,9,2,2,1};
for(int i = 0; i < var1.size(); i++)
{
for(int n = 0; n < 10; n++)
{
int product = 0;
product = var1[i] * arr[n];
var1[i] = product;
}
}
there is a short output of this result:
245
-33
-231
25
50
400
-1008
32
So if im not mistaken this is what you want right.
where totalProduct will hold the product of every product and arr2 holds your columns. I added resultAsString so you have the result as string
note the var.at(i)-'0' which does the convertion you want or i think you are looking for.
for the conversion from int to string im using
std::stringstream ss;
ss << product;
a less C++ aproach would have been the atoi(product) function. or if using c++ 11 std:to_string(product)
Hope it helps
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::string var1 = "1232253759";
int arr[] = {5,3,7,1,2,8,9,2,2,1};
int arr2[var1.size()];
int totalProduct = 0;
std::string resultAsString = "";
for(int i = 0; i < var1.size(); i++)
{
// for(int n = 0; n < 10; n++)
// {
int product = (var1.at(i)-'0') * arr[i];
// std::cout << product << "\n";
arr2[i] = product;
std::stringstream ss;
ss << product;
resultAsString += ss.str();
totalProduct += product;
//}
}
// for (int i = var1.size() - 1; i >= 0; i--)
// std::cout << arr2[i] << " ";
std::cout << resultAsString;
}
var1[i] is a char, not an int. char implicitly cast to int and calculation goes wrong. You need to map char with number to number itself ('1' -> 1, '2' -> 2). To do it subtract value of '0'. I.e. var1[i] - '0' it's number for char
I am coding an assignment for my class where a user will input 10 letter answers, and the program will return a grade. I recently changed my char arrays to string arrays, because I think it makes it easier to read.
I went to debug my code and am now getting the error "Deubug Assertion Failed." I do not know what this means or how to fix it.
Any help would be appreciated.
Thanks!
Below is my code:
// Lab 8
// programmed by Elijah Barron
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
//Function headers
string inputAnswers(string given);
int numCorrect(string correctAnswers, string given);
int main()
{
string correctAnswers = "BCADBADCAB";
string given;
int numRight = 0;
inputAnswers(given);
numCorrect(correctAnswers, given);
double grade = 10 * numRight;
cout << "Your quiz grade is " << grade << "%" << endl;
return 0;
}
//Get the answers
string inputAnswers(string given)
{
for (int n = 0; n < 10; n++)
{
cout << "Please enter your answer for question #" << n + 1 << " ";
cin >> given[n];
}
return given;
}
//Find if answers are correct or incorrect
int numCorrect(string correctAnswers, string given)
{
int numRight = 10;
int n = 0;
for (int n = 0; n < 10; n++);
{
if (given[n] != correctAnswers[n])
numRight -= 1;
}
return numRight;
}
The immediate issue is that given will start off as an empty string as you haven't assigned it a value:
cin >> given[n];
is causing the assert failure because you're trying to change the first (second, third etc) character in a string with a length of zero. To fix the assert problem (but not the program, which will always return 0%), just initialise the string:
string given = "ZZZZZZZZZZ";
To fix the rest of the stuff (btw this isn't the only way):
Change:
string inputAnswers(string given); //for both prototype and function.
to:
void inputAnswers(string& given); //pass by reference instead of pass by value.
//also get rid of "return given;"
Change:
int n = 0; //the n here is different to the one in the next line
for (int n = 0; n < 10; n++); //this n's scope begins and ends here thanks to the semicolon
{//the code here is executed once, this isn't in the loop!
if (given[n] != correctAnswers[n]) //we're using the first n here, which is 0.
numRight -= 1;
}
to:
for (int n = 0; n < 10; n++) //only one n variable and no semicolon
{// now this is in the loop and will execute 10 times.
if (given[n] != correctAnswers[n])
numRight -= 1;
}
Don't bother with this line:
int numRight = 0; //Set at 0 and then never changed.
and change:
numCorrect(correctAnswers, given);
to:
int numRight = numCorrect(correctAnswers, given); //declared when necessary and assigned the correct value
You either want to reserve enough space in your vector to hold 10 characters, or use push_back to populate the vector. Indexing a vector with [] won't grow the vector for you.
EDIT:
Ignore the first part about reserve. That doesn't stop the debug assertion. You will want to change this
cin >> given[n];
To something like this:
char input;
cin >> input;
given.push_back(input);
Here is v1.0 of the binary_to_decimal converter I wrote. I want to make several changes as I keep improving the spec. Classes and pointers will be added as well in the future. Just to keep me fresh and well practiced.
Well, I now want to implement an error-correcting loop that will flag any character that is not a 0 or a 1 and ask for input again.
I have been trying something along the line of this code block that worked with an array.
It might be way off but I think I can tweak it. I am still learning 0_0
I want to add something like this:
while ((cin >> strint).get())
{
cin.clear(); //reset the input
while (cin.get() != '\n') //clear all the way to the newline char
continue; //
cout << "Enter zeroes and/or ones only! \n";
}
Here is the final code without the error-correcting loop:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
const int MAX = 100;
int conv(int z[MAX], int l[MAX], int a);
int main()
{
int zelda[MAX];
int link[MAX];
string strint;
int am;
cout << "Enter a binary number: \n";
(cin >> strint).get(); //add error-correction to only read 0s and 1s.
am = strint.size();
cout << am << " digits entered." << endl;
int i = 0;
int p = 0;
while (i < am)
{
zelda[i] = strint[p] - '0'; //copies the string array elements into the int array; essentially STRING TO INT (the minus FORCES a conversion because it is arithmetic) <---- EXTREMELY CLEVER!
++i;
++p;
}
cout << conv(zelda, link, am);
cin.get();
return 0;
}
int conv(int zelda[MAX], int link[MAX], int length)
{
int sum = 0;
for (int t = 0; t < length; t++)
{
long int h, i;
for (int h = length - 1, i = 0; h >= 0; --h, ++i)
if (zelda[t] == 1)
link[h] = pow(2.0, i);
else
link[h] = 0;
sum += link[t];
}
return sum;
}
thanks guys.
I'm not completely sure of what you're trying to do, but I think what you're wanting is string::find_first_not_of. There's an example included in that link. You could have something like: myString.find_first_not_of("01");
If the return value is string::npos, then there are no characters in the string other than 1 or 0, therefore it's valid. If the return value is anything else, then prompt again for valid input and continue looping until the input's valid.