Debug Assertion Failed! Error during vector.earse() call - c++

The code below keeps getting me a "Debug Assertion Failed!" error. I think I've isolated it to:questions.erase(questions.begin() + number);
The goal of the code is to randomly ask one of the questions from the test bank vector "questions". I haven't entered all the questions yet because I was trying to figure out the mechanics before hand.
Thanks in advance for your help!
int nomen()
{
int number;
string ans = "No Answer";
cout << "\nIn the Nomenclature Game you will be asked to name chemical compounds or give their UPAC symbols." << endl;
vector<string> questions;
vector<string> answers;
questions.push_back("MgO");
answers.push_back("magnesium oxide");
srand((unsigned)time(0));
number = (rand () % questions.size()) + 1;
for (int i = 0; i < questions.size(); ++i)
{
cout << questions[number] << endl;
questions.erase(questions.begin() + number);
}
return 0;
}

questions.erase(questions.begin() + number); is off the end of the array.
questions.begin() is equivalent to position 0 and
number is equal to questions.size()
So 0 + size = size which is 1 past the end of the vector.

This expression
number = (rand () % questions.size()) + 1;
yields either 1 (when rand() returns any value except 0) or 2 (when rand() returns 0).
Your vectors have sizes equal to 1.
Thus in this statement
questions.erase(questions.begin() + number);
iterator questions.begin() + number is invalid if number is equal to 2. If number is equal to 1 then questions.begin() + number is equivalent
to questions.end()
Also in the loop
for (int i = 0; i < questions.size(); ++i)
{
cout << questions[number] << endl;
questions.erase(questions.begin() + number);
}
you are trying to erase the same element that can be already erased in the preceeding iteration.

Related

comparing a string at index i to a value in C++

So im working on a class assignment where I need to take a base 2 binary number and convert it to its base 10 equivalent. I wanted to store the binary as a string, then scan the string and skip the 0s, and at 1s add 2^i. Im not able to compare the string at index i to '0, and im not sure why if(binaryNumber.at(i) == '0') isnt working. It results in an "out of range memory error". Can someone help me understand why this doesnt work?
#include <iostream>
using namespace std;
void main() {
string binaryNumber;
int adder;
int total = 0;
cout << "Enter a binary number to convert to decimal \n";
cin >> binaryNumber;
reverse(binaryNumber.begin(),binaryNumber.end());
for (int i = 1; i <= binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') { //THIS IS THE PROBLEM
//do nothing and skip to next number
}
else {
adder = pow(2, i);
total = adder + total;
}
}
cout << "The binary number " << binaryNumber << " is " << total << " in decimal form.\n";
system("pause");
}
Array indices for C++ and many other languages use zero based index. That means for array of size 5, index ranges from 0 to 4. In your code your are iterating from 1 to array_length. Use:
for (int i = 0; i < binaryNumber.length(); i++)
The problem is not with the if statement but with your loop condition and index.
You have your index begin at one, while the first character of a string will be at index zero. Your out memory range error is caused by the fact that the loop stops when less than or equal, causing the index to increase one too many and leave the memory range of the string.
Simply changing the loop from
for (int i = 1; i <= binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') {
}
else {
adder = pow(2, i);
total = adder + total;
}
}
To
for (int i = 0; i < binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') {
}
else {
adder = pow(2, i);
total = adder + total;
}
}
Will solve the issue.
Because your started from 1 and not 0
for (int i = 1; i <= binaryNumber.length(); i++)
Try with that
for (int i = 0; i < binaryNumber.length(); i++)

Print divisors in order using theta(n) efficiency

I'm struggling to implement this correctly. I want to create a function that determines all of the divisors of the user input userNum and outputs them to the user. When userNum = 16 i'm getting the output 1 16 2 8. I didn't expect the order to be correct, but i'm missing 4 and am struggling to figure out why. Any thoughts? I'm trying to do this in theta(sqrt(num)) efficiency.
void PrintDivisors(int num);
int main()
{
int userNum;
//Request user number
cout << "Please input a positive integer >=2:" << endl;
cin >> userNum;
PrintDivisors(userNum);
return 0;
}
void PrintDivisors(int num)
{
int divisorCounter;
for (divisorCounter = 1; divisorCounter < sqrt(num); divisorCounter++)
{
if (num % divisorCounter == 0 && num / divisorCounter != divisorCounter)
cout << divisorCounter << endl << num / divisorCounter << endl;
else if (num % divisorCounter == 0 && num / divisorCounter == divisorCounter)
cout << divisorCounter << endl;
}
}
Update: I have all the numbers printing, but still trying to determine how to print them in order while remaining within theta sqrt(n) efficiency
Change loop termination condition operation to <=, now you will observe 4.
Get rid of sqrt function call. Better use this loop
for (divisorCounter = 1; divisorCounter * divisorCounter <= num; divisorCounter++)
Make sure to check your edge conditions carefully.
What is sqrt(num)?
What is the largest divisorCounter that will pass the test in the for loop?
Would 4 pass the test?
I think if you look carefully at that line with these three questions in mind you will squash the bug.
For making it run in sqrt(n) time complexity:
For any n = a X b. either a<=sqrt(n) or b<=sqrt(n).
So if you can find all divisors in range [1,sqrt(n)] you can find other divisors greater than sqrt(n)
You can use a for loop to traverse numbers in range 1 to sqrt(n) and find all the divisors less than sqrt(n), which at the same time you can also use to find other numbers greater than(or equal to) sqrt(n).
Suppose a number i < sqrt(n) is divisor or n. In that case the number k = n/i will also be divisor of n. But bigger than sqrt(n).
For printing numbers in sorted order:
During finding divisors in range [1,sqrt(n)] print only divisor in range [1,sqrt(n)] You can use an array/vector to store numbers in range [sqrt(n),n] and print them after the for loop ends. Here is a sample code
vector<int> otherNums;
for(i=1;i*i<n;i++) {
if(num%i==0){
cout<<i<<endl;
otherNums.push_back(n/i);
}
}
if(i*i == n) otherNums.push_back(i);
for(i=(int)v.size() - 1 ;i>=0;i--)
cout<<otherNums[i]<<endl;
This is the solution I ended up using, which saves space complexity too. I was struggling to think of effective ways to loop over the solution in ascending order, but this one runs very fast and is nicer than appending to a vector or array or some weird string concatenation.
void printDivisors(int num)
{
for (int k = 1; k*k < num; k++)
{
if (num % k == 0)
cout << k << " ";
}
for (int d = sqrt(num); d >= 1; d--)
{
if (num % d == 0)
cout << num / d << " ";
}
cout << endl;
}

C++ Why is that my output for str [i] is empty?

Below are my codes:
char str [80];
int n;
n = MAX + ( rand () % 1000 + 1);
cout << "number: " << n << endl;
constructArray(str, n);
void constructArray (char str [], int n)
{
for (int i = 0; i < n; i++)
{
while (n > 0)
{
// get last pair of digits
str [i] = n%10;
n/= 10;
}
cout << str[i] << endl;
}
}
I can't figure out why my compiler doesnt output any values.
It works if I didnt implement array.
Any help will be appreciated.
In the first iteration of your for loop, when while is executed for the first time (i=0), n will be reduced to 0. Thus your for loop will execute only once. This will lead to only str[0] being set. Others already pointed out that char cant store large numbers, but this is differnt problem.
There are few problems with you code.
You are storing integer in char type array.
for loop will only be executed only once because while loop make n = 0.
hence only str[0] will be assigned.
In the while loop,the n is still divided by 10 until n is reduced to 0. Then the for loop will finished. So only output str[0].

Binary Search in 2D Array 3

I need to find a number in the 2D array.
Columns are sorted (from smallest value to the biggest).
Here is my code:
const int SIZE = 4;
const int NOT_FOUND = 1;
int binarySearch(int mat[][SIZE], int &line , int num);
void main()
{
int num, index, mat[SIZE][SIZE] = { 11,1,5,11,
11,6,7,2,
8,7,7,7,
0,12,9,10 };
int line = sizeof(mat) / sizeof(mat[0][0]);
cout << "please type a number to search: " << endl;
cin >> num;
index = binarySearch(mat, line, num);
if (index == NOT_FOUND) {
cout << "The value: " << num << "doesn't exist in the array\n";
}
else {
cout << "The value: " << num << " exists in line " << line+1
<<" and column: " << index+1 << endl;
}
system("pause");
}
int binarySearch(int mat[][SIZE], int &line, int num)
{
for (int j = 0; j < SIZE; j++)
{
int low = 0;
int high = SIZE - 1;
int middle;
while (low <= high)
{
middle = (low + high) / 2;
if (num == mat[middle][j])
{
line = middle;
return j;
}
else if (num < mat[middle][j]) {
high = middle - 1;
{
else {
low = middle + 1;
}
}
}
return NOT_FOUND;
}
The program doesn't find all the numbers in the array.
Something doesn't work.
What is the problem?
Your binarySearch doesn't go through all the numbers, it checks the first number, so in your case 11, then it moves to the next number, but it skips the whole row of numbers (1, 5, 11) and the first number in second row and then moves to the next second number which will be 6 in second row.
Since you have a Matrix of number it consists of Rows and Columns, that means you have to create two loops for(...), once for the Rows and one for the Columns so you can go through all the numbers in your 2D array.
I recommend setting a Break point on the binarySearch function and going through with that, it'll help you a lot.
A few things that I see wrong in your code are ::
1) It appears that you are applying binary search to every column in your input array, and if the number is not found in the corresponding column, you increment j and move to the next column.
The most important thing about binary search is "The array in which you are searching should always be sorted". Since here you are searching columns, all your columns shall be sorted! Which appears unsorted in the code above! Which is a major reason why you don't find most elements. So, your input array shall look something like this (if you want to apply binary search) ::
int mat[SIZE][SIZE] = { 0,1,5,2,
8,6,7,7,
11,7,7,10,
11,12,9,11 }
All columns sorted in ascending order here!
2) The value of the variable NOT_FOUND you have set it to 1 and from your function you return the column number from where you found the element. So, if you found the element in the 2D array in column 1 your program will print Element Not Found because the condition if (index == NOT_FOUND) evaluates to true if the element was found in column 1. So, a better solution would be to change the value of NOT_FOUND to some negative value, since it can never be the column number in a valid case. Something like this ::
const int NOT_FOUND = -1;
Ideone link of code :: http://ideone.com/9cwHnY

How to sort an array based on amount of unusual digits

I have to write a function that accepts an array of integers as arguments
and display back to the user the "unusual" digits. Digits that appear only
in one integer and not the rest, and then sort the array so that the integer
with the largest occurrences of unusual digits is to be moved to the first
element of the array, then followed by the integer with the next
largest number of occurrences of unsual digits.
Input:
113
122
1000
Output:
There is 3 unusual digits:
0 occurs 3 times in 1000
2 occurs 2 times in 122
3 occurs 1 time in 113
Sorted:
1000
122
113
My question is how can I retrieve the integers that were associated with the unusual digits so that I can sort them in the future?
I would like to know which integer digit 0 came from and how many times it occurred in that integer.
Here's what I have so far, I apologize if the code is bad. I am not allowed to use any additional libraries other than iostream and all function calls must be written myself.
#include <iostream>
using namespace std;
void getUncommon(int* iAry, int size) {
const int size2 = 10;
int* tmpAry = new int[size];
int totalCount[size2] = { 0 };
int currentCount[size2] = { 0 };
int totalUncommon = 0;
int i, j;
for (i = 0; i < size; i++) {
tmpAry[i] = iAry[i];
if (tmpAry[i] < 0)
tmpAry[i] *= -1;
for (j = 0; j < size2; j++)
currentCount[j] = 0;
if (tmpAry[i] == 0) {
currentCount[0] = 1;
}
while (tmpAry[i] / 10 != 0 || tmpAry[i] % 10 != 0){
currentCount[tmpAry[i] % 10] = 1;
tmpAry[i] /= 10;
}
for (j = 0; j < size2; j++) {
totalCount[j] += currentCount[j];
}
}
for (i = 0; i < size2; i++) {
if (totalCount[i] == 1) {
totalUncommon++;
}
}
cout << "Total of uncommon digits: " << totalUncommon << endl
<< "Uncommon digits:\n";
if (totalUncommon == 0) {
cout << "\nNo uncommon digits found.";
}
else {
for (i = 0; i < size2; i++) {
if (totalCount[i] == 1) {
cout << i << endl;
}
}
}
return;
}
int main(){
int* my_arry;
int size;
int i;
cout << "How many integers? ";
cin >> size;
my_arry = new int[size];
for (i = 0; i < size; i++) {
cout << "Enter value #" << i + 1 << " : ";
cin >> my_arry[i];
}
cout << "\nThe original array:" << endl;
for (i = 0; i < size; i++) {
cout << my_arry[i] << endl;
}
cout << "\nCalling function -\n" << endl;
getUncommon(my_arry, size);
delete[] my_arry;
return 0;
}
Thanks ahead of time.
You can create a map with the digits 0 1 2 ... 9 as the key, and a pair of pointer to/index of integer containing the digit and number of occurrences of the digit in the integer as the value of the key-value pair.
Start iterating on the integer list, extracting the digits and their number of occurrences from each integer. You can do that by either using the modulo operator, or using string functions (after converting the integer to string).
Now, for each integer, access the map of digits for all the digits in the integer, and if the value is uninitialised, update the value with the pointer/index to this integer and the number of occurrences of the digit in this integer. If the map entry is already populated, that means that it's not an "unusual" digit. So you can mark that map entry with a marker that conveys that this particular digit is not "unusual" and hence no need to update this entry.
After iterating over the entire integer list in this manner, you can iterate the map to find out which digits are unusual. You can also access the containing integer from the pointer/index in the value portion of the map's key-value pair. You can sort these entries easily using any sorting algorithm (since the number of values to be sorted is very small, no need to worry about time complexity, pick the easiest one) on the number of occurrences value.