Vector and for doesn't produce results - c++

I'm working on a simple game (rock, paper, scissors) and I got this problem when I try to populate a vector with using elements of another vector as conditions. The code maybe is more easy to understand:
#include "stdafx.h"
#include "../../Library/std_lib_facilities.h"
// With the fibonacci series I can generate a secret sequence of number
int fib(int n){
if (1 == n || 2 == n) {
return 1;
}
else {
return fib(n - 1) + fib(n - 2);
}
}
// It shows the list of element in a given vector
void showVector(vector<int>myVector, string nameVector) {
cout << "\n\n";
cout << nameVector << " Debug: | ";
for (int i = 1; i < 10; i++) {
cout << myVector[i] << " | ";
}
cout << "\n\n";
}
// String variant
void showVector(vector<string>myVector, string nameVector) {
cout << "\n\n";
cout << nameVector << " Debug: | ";
for (int i = 1; i < 10; i++) {
cout << myVector[i] << " | ";
}
cout << "\n\n";
}
// Generate a sequence of number in a vector
vector<int> generateCode(int input) {
vector<int>myVector;
for (int i = 1; i <= 10; i++) {
myVector.push_back(fib(i + input) % 3);
}
return myVector;
}
int main()
{
// Secret sequence of moves, based on the value (0, 1 or 2) i will show Rock, Paper or Scissor
vector<int>fibSeries;
vector<string>movSeries;
// Initialization and settings
int input = 0;
cout << "Digit an integer to start: ";
while (cin >> input) {
// Check the number to make sure is a valid one (i will implement a check later) and generate the secret code
fibSeries = generateCode(input);
// For each 0 i'll put Rock in the vector, same for 1 ( in this case paper ) and 2 ( scissor )
for (int i = 0; i <= fibSeries.size(); i++) {
if (fibSeries[i] == 0){
movSeries.push_back("Rock");
}
else if (fibSeries[i] == 1) {
movSeries.push_back("Paper");
}
else if (fibSeries[i] == 2) {
movSeries.push_back("Scissor");
}
else {
movSeries.push_back("Rock");
}
}
// Shows the vector graphically, for debug.
showVector(fibSeries, "fibisSeries");
showVector(movSeries, "movSeries");
// So for a combination of 1 - 2 - 0 - 1
// The result should be: Paper - Scissor - Rock - Paper
}
return 0;
}
After i execute the code, i get an (Abort). I don't understand, I'm new to C++ so please forgive me if is a stupid error. And most of the code is complex becouse I have rules to follow, so for example if I didn't study something i can't use it here. I just want to know why the code don't want me to use the for with the vector!

for (int i = 0; i <= fibSeries.size(); i++)
As #Yola mentions, you iterate one element more than you have:
if you have the vector std::vector<char> v = {'a', 'b', 'c'};, the elements can be accessed as:
v[0] (-> 'a')
v[1] (-> 'b')
v[2] (-> 'c')
As a rule, your max index will be length - 1.
for (int i = 0; i <= fibSeries.size(); i++)
iterates from 0 to less then or equal to size(); that is, 0, 1, 2, 3 (4 elements, in a 3 elements vector).
Correct code should be:
for (int i = 0; i < fibSeries.size(); i++)
^^^

So as has already been stated, your problem is that you should always use < size because indexing is 0-based <= size will read off the end of allocated space.
But a couple comments if I may, c++11 introduced a new style of range based for-loops which will save you from having to write the condition and iteration expressions at all:
map<int, string> movSeries = { { 0, "Rock"s }, { 1, "Paper"s }, { 2, "Scissors"s } };
vector<int> fibSeries(10);
auto input = 0;
while(cin >> input) {
for(auto& i : fibSeries) {
i = fib(input++) % 3;
}
cout << "\n\nDebug | ";
copy(cbegin(fibSeries), cend(fibSeries), ostream_iterator<int>(cout, " | "));
cout << "\n\n\n\nDebug | ";
for(const auto i : fibSeries) {
cout << movSeries[i] << " | ";
}
cout << endl << endl;
}

Related

How do i sum all numbers using loop?

For Example, I have number 1 + 6 + 7 + 12 + 13 + 18+.....+ n (n is the input from users which represent the number of elements) the index of this number starts from 1 by this it means​ that if the index is an odd number (1,3,5...) I want to increment the element at that index by 5 and if the index is an even number I want to increment the element at that index by 1 until I reach the of n number of elements. What I want is to sum all those numbers.
Sorry, It may hard to understand because of my poor English So let me write some of my C code here:
using namespace std;
int i, n, result = 0;
cout << "Input number to sum: ";
cin >> n;
// Finding result
for (i = 0; i <= n; i++){
if (i % 2 == 0) {
result +=i;
} else {
result += i * 5;
}
}
// Make last number have equal sign "1+6+7+12 = 36"
for (i = 0; i <= n; i++){
if (i == n) {
cout << i..?? << "=";
} else {
cout << i..?? << "+";
}
}
// Print result out
cout << result;
return 0;
}
Combine the computation with the output (I usually preach the opposite, but in this case it actually simplifies matters).
for (int i = 0; i <= n; i++)
{
int value = i % 2 == 0 ? i + 1 : i + 5;
cout << (i > 0 ? " + " : "") << value;
result += value;
}
cout << " = " << result;
I agree with the molbdnilo that combining calculations and output in this case, simplify the code.
I don't agree with the algorithm, though, given OP's description.
In the following the calculations are repeated to output the result
#include <iostream>
int main()
{
int n;
std::cout << "Input number to sum: ";
std::cin >> n;
auto update = [] (int i) { return i % 2 == 0 ? 1 : 5; };
int result = 0;
int value = 0;
for (int i = 0; i < n; i++)
{
value += update(i);
result += value;
}
std::cout << '\n';
for (int i = 0, value = 0; i < n; i++)
{
value += update(i);
std::cout << (i > 0 ? " + " : "") << value;
}
std::cout << " = " << result;
}
Testable here.
I agree with molbdnilo's answer. However the algorithm some changes.
The index starts from 1 , so value check for i in for loop should be
for (int i = 0; i < n; i++)
while updating the values, increment should be done on value and not on i.
Here is my solution:
using namespace std;
int main()
{
int i, n, result, value = 0;
cout << "Input number to sum: ";
cin >> n;
for (i = 0; i < n; i++)
{
value = i % 2 == 0 ? value + 1 : value + 5;
cout << (i > 0 ? " + " : "") << value;
result += value;
}
cout << " = " << result;
return 0;
}
Testable here

Continuous x no. of A and then after (n-x) no.s of B

I am stuck in one of the problem related string in c++. My logic has worked well for some test cases, but not for all test cases. Please suggest me the actual logic of the following question::
I am given a string s of n character, comprising only of A's and B's . I can choose any index i and change s(i) to either A or B. Find the minimum no. Of changes that you must make to string S such that the resultant string is of format : AAAAA.....BBBBB. In other words, your task is to determine minimum no. of changes such that string s has x no. of A's in the beginning, followed by the remaining (n-x) no. of B's.
my code::
#include<bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n, i, flag = 0;
cin >> n;
string str;
cin >> str;
int cnt = 0, cnt1 = 0;
for (i = 0; i < str.length(); i++) {
if (str[i] == 'A') {
cnt++;
} else {
cnt1++;
}
}
int pp = 0;
//cout << cnt << " " <<cnt1;
for (i = 0; i < cnt; i++) {
if (str[i] == 'B') {
pp++;
}
}
for (i = cnt; i < n; i++) {
if (str[i] == 'A' && str[i - 1] != 'A') {
pp++;
}
}
cout << pp << endl;
}
}
For example: AAB = 0 changes, BABA= 2 changes , AABAA= 1 changes
How to approach this question. Do respond!!!
I wrote the following code to compute the number of changes needing to order a string containing unorderd A e B according to the order that shall be "A[...A]B[...B]". (function countChanges).
The algorithm (countChanges) used to count modifications acts in three steps:
Step 1: counts how much 'A' chars are in the string (cnt).
Step 2: scans how much 'B' chars are in the first cnt chars of the string increasing a counter (sum) for each encounterd 'B'.
Step 3: scans how much 'A' chars are in the remaining chars of the string after the 2nd step increasing a counter (sum) for each encountered 'A'.
At the end of the function sum is the expected result.
The code also computes and executes the minimum number of swaps needing to obtain the string ordered according to the requirement.
The code contains two evaluation functions (the code under the main):
cntChanges. It computes the needing number of changes (The code gives the result as foreseen changes).
executeSwaps. It performs swaps on the string, counts them and may or may not show the steps performed.
Code result:
Do you have a code composed of A and B? [y]es/[n]o/[I] do it/[q]uit y
Insert your code? BABA
Do you want to print swap steps? [y]es/[n]o y
Input: BABA
Step 1 BABA swap(3,0) ==> AABB
Result AABB performed with 1 swap - foreseen changes 2
--
Do you have a code composed of A and B? [y]es/[n]o/[I] do it/[q]uit n
How much codes do you want to generate? 5
What's your preferred length for all generated codes? 10
Do you want to print swap steps? [y]es/[n]o y
Input: AAAAABAABB
Step 1 AAAAABAABB swap(7,5) ==> AAAAAAABBB
Result AAAAAAABBB performed with 1 swap - foreseen changes 2
--
Input: ABBABAAABA
Step 1 ABBABAAABA swap(9,1) ==> AABABAAABB
Step 2 AABABAAABB swap(7,2) ==> AAAABAABBB
Step 3 AAAABAABBB swap(6,4) ==> AAAAAABBBB
Result AAAAAABBBB performed with 3 swaps - foreseen changes 6
--
Input: AAABBAABBB
Step 1 AAABBAABBB swap(6,3) ==> AAAABABBBB
Step 2 AAAABABBBB swap(5,4) ==> AAAAABBBBB
Result AAAAABBBBB performed with 2 swaps - foreseen changes 4
--
Input: BABAABBABB
Step 1 BABAABBABB swap(7,0) ==> AABAABBBBB
Step 2 AABAABBBBB swap(4,2) ==> AAAABBBBBB
Result AAAABBBBBB performed with 2 swaps - foreseen changes 4
--
Input: AAABAABAAA
Step 1 AAABAABAAA swap(9,3) ==> AAAAAABAAB
Step 2 AAAAAABAAB swap(8,6) ==> AAAAAAAABB
Result AAAAAAAABB performed with 2 swaps - foreseen changes 4
--
The code:
#include <iostream>
#include <ctime>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
unsigned int executeSwaps(string &x, bool printSteps);
unsigned int cntChanges(const string& x);
unsigned int cntChangesJarod42(string const &x);
unsigned int cntChangesDamien(string const &x);
void questionToStart(int &c, size_t &cl, char &ync, char &ynps, string &x);
string generateCode(size_t n);
const char char1='A';
const char char2='B';
int main(void)
{
srand(static_cast<unsigned int>(time(nullptr)));
int c;
size_t cl;
char ync='n';
char ynps='n';
string x;
x.clear();
do {
questionToStart(c,cl,ync,ynps,x);
if (ync == 'q')
break;
for(int i=0;i<c;i++) {
unsigned int cnt=0;
if (ync=='n') {
x=generateCode(cl)
}
/* unsigned int fc2 = cntChangesJarod42(x);
unsigned int fc1 = cntChangesDamien(x);*/
unsigned int fc3 = cntChanges(x);
cout << "Input: " << x << endl;
cnt=executeSwaps(x, (ynps=='y')?1:0);
cout << "Result " << x << " performed with "
<< ((cnt>0)?to_string(cnt):"no")
<< " swap"
<< ((cnt>1)?"s ":" ") << " - foreseen changes " << fc3 << endl << "--" << endl;
/* << "foreseen changes (#Damien) " << fc1
<< " - foreseen changes (#Jarod42) " << fc2
<< endl << endl;*/
}
} while(ync != 'q');
return 0;
}
unsigned int cntChanges(const string& x)
{
const char * s;
unsigned int cnt=0,sum=0,i;
if (x.empty())
return 0;
s=x.c_str();i=0;
// count char1
while(*(s+i))
if (*(s+i++) == char1)
cnt++;
/* verify how much elements, from start to cnt,
* are different than char1 (equal to char2).
*/
for(i=0;i<cnt;i++)
if (*(s+i)==char2)
sum++;
cnt=static_cast<unsigned int>(strlen(s));
/* verify how much of the remaining elements
* are different than char2 (equal to char1).
*/
for(;i<cnt;i++)
if (*(s+i)==char1)
sum++;
return sum;
}
// #Jarod42
unsigned int cntChangesJarod42(const string& s)
{
if (s.empty()) { return 0; }
std::vector<std::size_t> switch_count(s.size());
{ // Count 'B' before index
unsigned int sum = 0;
std::size_t i = 0;
for (auto c : s) {
switch_count[i++] += sum;
sum += c == 'B';
}
}
{ // Count 'A' after the index
unsigned int sum = 0;
std::size_t i = 0;
for (auto c : std::string(s.rbegin(), s.rend())) {
switch_count[s.size() - 1 - i++] += sum;
sum += c == 'A';
}
}
return static_cast<unsigned int>(*std::min_element(switch_count.begin(), switch_count.end()));
}
// #Damien Algorithm
unsigned int cntChangesDamien (string const &x)
{
size_t n = x.length();
int cntCh_1 = 0, cntCh_2 = 0;
// there's nothing to swap!! :p
if (n < 2)
return 0;
for (size_t i = 0; i < n; ++i) {
if (x.at(i) == char1) {
cntCh_1++;
} else {
// x.at(i) is equal to char1
cntCh_1 = min (cntCh_2, cntCh_1);
// Now the foreseen swap are equal to cntCh1
cntCh_2++;
}
}
return static_cast<unsigned int>(std::min (cntCh_2, cntCh_1));
}
unsigned int executeSwaps(string &x, bool printSteps)
{
unsigned int cnt =0;
size_t apos=0;
size_t bpos=0;
// cout << "Start: " << x << " " << apos << " " << bpos << endl;
do {
apos=x.find_last_of(char1);
if (apos == string::npos)
break;
bpos=x.find_first_of(char2);
if (bpos == string::npos)
break;
if (apos>bpos) {
++cnt;
if (printSteps) {
cout << "Step " << cnt << " " << x << " swap(" << apos << "," << bpos <<") ==> ";
}
x.at(bpos)=char1;
x.at(apos)=char2;
if (printSteps)
cout << x << endl;
}
} while(apos>bpos);
return cnt;
}
string generateCode(size_t n)
{
string x;
x.clear();
size_t i,cb=0;
char ch;
if (n==0) {
n=rand()%10;
}
for (i=0;i<n-1;i++) {
ch = ( char1 + (rand()&1) );
if (ch == char2 )
cb++;
x +=ch;
}
if (cb==n-1) {
ch=char1;
} else if (cb==0) {
ch=char2;
} else {
ch=( char1 + (rand()&1) );
}
x += ch;
return x;
}
void questionToStart(int &c, size_t &cl, char &ync, char &ynps, string &x)
{
int ex=1;
do {
ex=1;
cout << "Do you have a code composed of "<<char1 << " and " << char2 <<"? [y]es/[n]o/[I] do it/[q]uit ";
cin >> ync;
switch(ync) {
case 'n':
cout << "How much codes do you want to generate? ";
cin >> c;
cout << "What's your preferred length for all generated codes? ";
cin >> cl;
break;
case 'I':
c=10; cl=(rand()&7)+9;
cout << c <<" attempts with " << cl << " characters long strings will be executed" << endl;
break;
case 'y':
c=1;
cout << "Insert your code? ";
cin >> x;
cl = x.length();
break;
case 'q':
break;
default:
ex=0;
}
} while(!ex);
if ( ync != 'q' ) {
if ( ync != 'I' ) {
cout << "Do you want to print swap steps? [y]es/[n]o ";
cin >> ynps;
} else {
ynps = 'y';
ync = 'n';
}
cout << endl;
}
}
As state by Tfry,
you might count the number of switch needed to have
XBBB
AXBB
AAXB
AAAX
which is the number of 'B' before the index + number of 'A' after the index.
Then take the minimum:
std::size_t count_switch_for_ab(const std::string& s)
{
if (s.empty()) { return 0; }
std::vector<std::size_t> switch_count(s.size());
{ // Count 'B' before index
int sum = 0;
std::size_t i = 0;
for (auto c : s) {
switch_count[i++] += sum;
sum += c == 'B';
}
}
{ // Count 'A' after the index
int sum = 0;
std::size_t i = 0;
for (auto c : std::string(s.rbegin(), s.rend())) {
switch_count[s.size() - 1 - i++] += sum;
sum += c == 'A';
}
}
return *std::min_element(switch_count.begin(), switch_count.end());
}
Demo.
The solution can be found in a simple loop, considering a 2-state process.
A state corresponds to the fact that for the given index, we decide to be in the A part or the B part. The transition from B state to A state is not allowed.
The corresponding number of changes up to index i can then be calculated iteratively.
For index i, let us call countA[i] the number of changes to get A only until index i, and let us call countB[i] the optimal number of changes up to i, assuming that somewhere before i, or at i time, we decided that the following part of the last string will containt B only.
It the current character s[i] is equal to A, then
countA[i] = countA[i-1]
countB[i] = countB[i-1] + 1
If the current character is B, then
countA[i] = countA[i-1] + 1
countB[i] = min (countB[i-1], countA[i-1])
if the last equation, countB[i] = countB[i-1] corresponds to the case that the transition to B state already occurs, and
countB[i] = countA[i-1] corresponds to the case that the transition occurs now.
In practice, we don't need an array to update countA and countB.
Here is the code:
#include <iostream>
#include <string>
int nb_changes (const std::string &s) {
int n = s.size();
if (n < 2) return 0;
int countA = 0, countB = 0;
for (int i = 0; i < n; ++i) {
if (s[i] == 'A') {
countB++;
} else {
countB = std::min (countA, countB);
countA++;
}
}
return std::min (countA, countB);
}
int main() {
std::string s;
s = "AAB";
std::cout << "number of changes for " << s << " is " << nb_changes(s) << "\n";
s = "BABA";
std::cout << "number of changes for " << s << " is " << nb_changes(s) << "\n";
s = "AABAA";
std::cout << "number of changes for " << s << " is " << nb_changes(s) << "\n";
}

Getting error in an array comparing program in a specific input

I have written a small program which compares two arrays with custom array size. Whenever I set the array size to 4, the program does not work correctly on comparing the fourth member of each array.
(when I set x to 4, the fourth array members does not get compared correctly)
This is the code:
#include <iostream>
using namespace std;
int main()
{
int x;
std::cin >> x;
int i =1;
int arr[x];
int arr2[x];
while(i <= x)
{
std::cout << "Enter row " << i << " of arr\n";
std::cin >> arr[i];
i++;
}
i = 1;
while(i <= x)
{
std::cout << "Enter row " << i << " of arr2\n";
std::cin >> arr2[i];
i++;
}
for(int a = 0;a <= x;a++)
{
if(arr[a] == arr2[a])
std::cout << "row " << a << " is true\n";
}
}
You have an out of bound access, which yields undefined behavior. Recall that indices into raw arrays start with zero, not with one. Hence,
int i = 0;
is the correct initialization of the index, while the first loop must be changed to
while (i < x) { /* ... */ }
Then, the assignment of i needs again to be adjusted to
i = 0;
and the two remaining loops to
while (i < x) { /* ... */ }
for (int a = 0; a < x; a++) { /* ... */ }
As a side note, you are using variable length arrays (arr and arr2), which is non-standard C++ (see this thread for more info). Prefer std::vector for a simple container with runtime-dependant size.
i = 1;
while(i <= x)
{
std::cout << "Enter row " << i << " of arr2\n";
std::cin >> arr2[i];
i++;
}
you are storing element in array starts with 1 index
for(int a = 0;a <= x;a++)
{
if(arr[a] == arr2[a])
std::cout << "row " << a << " is true\n";
}
But comparing by starting from 0 index.
keep consistency either start from 0 or 1
for(int a = 1;a <= x;a++)
{
if(arr[a] == arr2[a])
std::cout << "row " << a << " is true\n";
}
it will work..

c++ sort: ranking list with same value of an array

I'm trying to show a ranking list of my array qt, which contains 5 numbers.
int i, j;
int qt[5] = {10,20,10,50,20};
int tempqt;
for (i=0; i<5; i++)
{
for(j=(i+1); j<5; j++)
{
if (qt[i] >= qt[j])
{
tempqt = qt[i];
qt[i] = qt[j];
qt[j] = tempqt;
}
}
}
for(i=0; i<5; i++)
{
cout << i+1 << ".number: " << qt[i] << endl;
}
normally, the 2 for-loops sort my array and the last for-loop displays my array ordered, so it looks like this:
1.number: 10
2.number: 10
3.number: 20
4.number: 20
5.number: 50
But I want to display the numbers with the same value as the same ranking position, so like this:
1.number: 10
1.number: 10
2.number: 20
2.number: 20
3.number: 50
The idea is to increase rank counter when meet different value in qt array.
i = 0;
int rank = 1, val = qt[i];
cout << rank << ".number: " << qt[i] << endl;
for(i=1; i<5; i++)
{
if (qt[i] != val) {
++rank;
val = qt[i];
}
cout << rank << ".number: " << qt[i] << endl;
}
Use std::sort to sort the array -- you won't get anywhere until the array is sorted.
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int qt[5] = { 10, 20, 10, 50, 20 };
sort(qt, qt + 5);
int count = 1;
for (int i = 0; i < 5; ++i)
{
if (i > 0)
{
if (qt[i] != qt[i - 1])
++count;
}
cout << count << ".number: " << qt[i] << endl;
}
}
Here is another solution using a map. This is more "lazy" in that there is no real "check if number already seen" logic involved. Just add numbers to a map, and print out the results in a loop.
If there are no memory constraints (you will need to create a map of the numbers, of course), and/or you need the array to remain stable (not sorted), then this could be an alternative.
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int qt[5] = { 10, 20, 10, 50, 20 };
std::map<int, int> IntMap;
// add entries to map, adding to a counter each time
for (int i = 0; i < 5; ++i)
IntMap[qt[i]]++;
// output the results.
int count = 1;
for (auto it = IntMap.begin(); it != IntMap.end(); ++it, ++count)
{
for (int i = 0; i < it->second; ++i)
cout << count << ".number: " << it->first << endl;
}
}
The map already sorts, so that's taken care of. Then the map is set up to count the number of times each number shows up, so that's taken care of. The only thing left is to write a loop that just goes through the map and prints the information.
See it here: http://ideone.com/q08SeX
I'd rather use a do while loop:
int p = 1, x = 0;
do
{
cout << p << ".number: " << qt[x++] << endl;
if (x < 5 && qt[x] != qt[x-1])
p++;
} while (x < 5);

Vector Appending

so far this is my code what i am trying to do is say the user inputs 1 2 3 and then presses -1, he or she will be asked to input another set of numbers say 9 8 7, what my programs is suppose to do is display them out as such 1 2 3 9 8 7, but rather it is displaying them like this 6 6 6 6 6 6, basically it counts how many numbers there are and displays that amount of numbers with that number. So can anyone help me out here, how do i make it so that it displays the two sets of numbers combined?
#include <iostream>
#include <vector>
using namespace std;
vector<int> append(vector<int> a, vector<int> b)
{
int n = a.size();
int m = b.size();
vector<int> c(n + m);
int i;
for (i = 0; i < n; i++)
c[i] = a[i];
for (i = 0; i < m; i++)
c[n + i] = b[i];
return c;
}
int main()
{
cout << "Please enter a set of numbers, insert -1 when done.\n";
vector<int>a;
bool more = true;
while (more)
{
int n;
cin >> n;
if (n == -1)
more = false;
else
a.push_back(n);
}
cout << "Please enter another set of numbers, insert -1 when done.\n";
vector<int>b;
more = true;
while (more)
{
int m;
cin >> m;
if (m == -1)
more = false;
else
b.push_back(m);
}
vector<int>d = append(a,b);
{
int i;
for (i= 0; i < d.size(); i++)
cout << d.size() << "\n";
}
}
That's because at the end you're printing the size, not the value:
cout << d.size() << "\n";
Should be:
cout << d[i] << "\n";
It is because when you are printing it, you are printing d.size instead of d[i].
cout << d.size() << "\n";
Would needs to be:
cout << d[i] << endl;