Buffer overrun warning - c++

This script spreads all the digits of a number in an array, so that by doing this: spread(number)[position] you can access the digit with relative position. Now the compilers gives me a Buffer overrun warning (C6386), which I assume is caused by exceeding an array bounds (correct me if I'm wrong), but I scripted the function such that such thing doesn't happen, and the program is still malfunctioning
#include <iostream>
#include <math.h>
using namespace std;
unsigned int size(long long int num)
{
unsigned int size = 1;
while (num >= pow(10, size)) size++;
return size;
}
int* spread(int num)
{
unsigned int digit;
int* nums = new int[size(num)];
for (unsigned int P = 0; P <= size(num) - 1; P++)
{
digit = num - num / 10 * 10;
num /= 10;
nums[P] = digit; //Right in this line the program doesn't seem to behave correctly
}
return nums;
}
int main()
{
cout << split(377)[0] << endl;
cout << split(377)[1] << endl;
cout << split(377)[2] << endl;
system("PAUSE");
return 0x0;
}
/*
Output of the program:
7
7
-842150451 <-- there should be a 3 here
Press any key to continue . . .
*/

The body of your for loop interferes with your end condition:
P=0, num=377, size(num) = 3, P <= 2 = true
P=1, num=37, size(num) = 2, P <= 1 = true
P=2, num=3, size(num) = 1, P <= 0 = false
The fix is to calculate size(num) up front and use that in your loop condition:
int numdigits = size(num);
for (int P=0; P < numdigits; P++) { ... }

{
unsigned int digit;
int* nums = new int[size(num)];
int P = 0;
while(num!=0)
{
digit = num - num / 10 * 10;
num /= 10;
nums[P++] = digit; //Right in this line the program doesn't seem to behave correctly
}
return nums;
}
You will store the digit until the number is 0.
Use this condition and your Code works.
But you have memory leaks...
You have to free dynamic memory!
Update: There is a short code, which works ;-)
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<size_t> spread(int const num)
{
string number = to_string(num);
vector<size_t> digits;
for(size_t i = 0; i < number.size(); ++i)
{
digits.push_back(number[i] - '0');
}
return digits;
}
int main()
{
auto vec = spread(12345000);
for (auto elem : vec)
{
cout << elem << endl;
}
system("PAUSE");
return 0x0;
}

Related

Counting times that a number repeats without array(c++)

I need a program to get 100 numbers between 0-20 and count the repition of the most repeated number.
Here is what I got for less amount for input (10 instead of 100) but ofc it's wrong.
#include <iostream>
using namespace std;
int main() {
int num, x,c;
for(int i=1; i<=10; i++) {
cin >> num;
if(num==x)
c++;
else
x=num;
}
cout << c;
return 0;
}
Assuming you mean the longest continuous sequence, here's one way you can do it:
#include <iostream>
int main() {
int max_val = 0, max_len = 0; // Overall longest
int cur_val = 0, cur_len = 0; // Current
for (int i = 0; i < 10; ++i) {
int val;
std::cin >> val; // read 1 number
if (val == cur_val) // if still counting the same, increment the length
++cur_len;
else { // else, set the max and reset current
if (cur_len > max_len) {
max_len = cur_len;
max_val = cur_val;
}
cur_len = 1;
cur_val = val;
}
}
// consider the very last sequence
if (cur_len > max_len) {
max_len = cur_len;
max_val = cur_val;
}
// Result
std::cout << "Longest seq: " << max_val << ", length: " << max_len << '\n';
}

Return all codes - String

Assume that the value of a = 1, b = 2, c = 3, ... , z = 26. You are given a numeric string S. Write a program to return the list of all possible codes that can be generated from the given string.
For most of the cases this code works but it gives wrong output for inputs which have numbers greater than 26. For eg: 12345.
#include <iostream>
#include <string.h>
using namespace std;
using namespace std;
int atoi(char a)
{
int i=a-'0';
return i;
}
char itoa(int i)
{
char c='a'+i-1;
return c;
}
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
return 1;
}
if(input.size()==1)
{
output[0]=output[0]+itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
for(int i=0;i<size1;i++)
{
output[i]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[i+size1]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return size1+size2;
}
int main(){
string input;
cin >> input;
string output[10000];
int count = getCodes(input, output);
for(int i = 0; i < count && i < 10000; i++)
cout << output[i] << endl;
return 0;
}
if i give input 12345, the output is:
"
abcde
awde
lcde
l"
instead of :
"
abcde
awde
lcde"
i got it fellow members. i did not initialised the size2 variable to zero. also i didn't use >= operator.
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
output[0]="";
return 1;
}
if(input.size()==1)
{
output[0]=itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2=0;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>=10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
int k=0;
for(int i=0;i<size1;i++)
{
output[k++]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[k++]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return k;
}
this is the final code for getCodes function. Thanks everyone :)
You can do that more simply with something like this:
#include <utility>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
void getCodesRec(unsigned int num, string& current, vector<string>& result)
{
// First and last chars for the codes
static constexpr char FIRST_CHAR = 'a';
static constexpr char LAST_CHAR = 'z';
if (num == 0)
{
// When there is no more number add the code to the results
result.push_back(current);
}
else
{
// Add chars to the existing code
unsigned int next = num;
unsigned int rem = next % 10;
unsigned int f = 1;
// While we have not gone over the max char number
// (in practice this loop will run twice at most for a-z letters)
while (next > 0 && rem <= (unsigned int)(LAST_CHAR - FIRST_CHAR) + 1)
{
next = next / 10;
if (rem != 0) // 0 does not have a replacement
{
// Add the corresponding char
current.insert(0, 1, FIRST_CHAR + char(rem - 1));
// Recursive call
getCodesRec(next, current, result);
// Remove the char
current.erase(0, 1);
}
// Add another number
f *= 10;
rem += f * (next % 10);
}
}
}
vector<string> getCodes(unsigned int num)
{
vector<string> result;
string current;
getCodesRec(num, current, result);
return result;
}
int main()
{
unsigned int num = 12345;
vector<string> codes = getCodes(12345);
cout << "Codes for " << num << endl;
for (string& code : codes)
{
cout << "* " << code << endl;
}
return 0;
}
Output:
Codes for 12345
* abcde
* lcde
* awde

Recursively storing integers in an array

I have problem with recursive functions.
I have to build a recursive function which creates an array of integer values corresponding to the digits of a given number.
For example, if I input a number like 3562, it should look like :
myArray[0] = 3
myArray[1] = 5
myArray[2] = 6
myArray[3] = 2
Here is my code :
#include <iostream>
using namespace std;
int myFunction(int num, int lenOfNum);
int main(){
int number;
int lengthCount = 0;
cout <<"Input numbers" << endl;
cin >> number;
int temp = number;
for(; number != 0; number /= 10, lengthCount++);
number = temp;
cout << myFunction(number, lengthCount) << endl;
}
int myFunction(int num, int lenOfNum){
int arr[lenOfNum];
if(num > 0){
for(int i = 0; i < lenOfNum; i++){
arr[i] = num/=10;
cout << "arr[" << i + 1 << " ]= " << arr[i] << endl;
}
return myFunction(num, lenOfNum);
}
else if(num == 0){
return 0;
} else;
}
The problem with your code is that you are calling int arr[lenOfNum] in each method call, which in short creates an array with a new reference to a memory location that can store lenOfNum integers.
To solve this, we declare the array in the main method and pass it as a parameter to the function.
int main() {
// somewhere in main after reading lenOfNum
int arr[lenOfNum];
// somewhere in main after declaring an array
myFunction(arr, number, lengthCount - 1);
}
and myFunction as
void myFunction(int *arr, int num, int idx) {
if (idx < 0) return; // you've completed processing the num
else if (num == 0) {
arr[0] = 0;
return;
}
arr[idx--] = num % 10;
myFunction(arr, num / 10, idx);
}
Using vector and rest part of your example
#include <iostream>
using namespace std;
void myFunction(vector<int> &arr, int num, int lenOfNum){
if (num < 0) {
return;
}
else if (num == 0) {
return;
}
int next_idx = lenOfNum - 1;
int digit = num % 10;
arr[next_idx] = digit;
myFunction(arr, num / 10, next_idx);
}
int main(){
int number;
int lengthCount = 0;
cout <<"Input numbers" << endl;
cin >> number;
int temp = number;
for(; number != 0; number /= 10, lengthCount++);
number = temp;
auto arr = vector<int>(lengthCount, 0);
myFunction(arr, number, lengthCount);
for(int i = 0; i < arr.size(); i++){
cout << "arr[" << i << " ]= " << arr[i] << endl;
}
}
Works for positive numbers
#include <vector>
#include <stdio.h>
std::vector<int> myFunction(int num)
{
std::vector<int> ret;
int irec = num / 10;
if (irec > 0)
ret = myFunction(irec);
ret.push_back('0' + (num % 10));
return ret;
}
int main(int argc, char *argv[])
{
std::vector<int> res = myFunction(539);
for(unsigned int i = 0; i < res.size(); i++)
printf("%c,", res[i]);
}

Significant C++ code execution slowdown

So I have to solve one USACO problem involving computing all the primes <= 100M and printing these of them which are palindromes while the restrictions are 16MB memory and 1 sec executions time. So I had to make a lot of optimisations.
Please take a look at the following block of code:
for(int i = 0; i < all.size(); ++i)
{
if(all[i] < a) continue;
else if(all[i] > b) break;
if(isPrime(all[i]))
{
char buffer[50];
//toString(all[i], buffer);
int c = all[i];
log10(2);
buffer[3] = 2;
//buffer[(int)log10(all[i])+1] = '\n';
//buffer[(int)log10(all[i])+2] = '\0';
//fputs(buffer, pFile);
}
}
Now, it executes in the satisfying 0.5 sec range, but when I change log10(2) to log10(all[i]) it skyrockets nearly to 2 seconds! For no apparent reason. I'm assigning all[i] to the variable c and it doesn't slow down the execution at all, but when I pass all[i] as parameter, it makes the code 4 times slower! Any ideas why this is happening and how I can fix it?
Whole code:
/*
ID: xxxxxxxx
PROG: pprime
LANG: C++11
*/
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <cstring>
#include <algorithm>
#include <list>
#include <ctime>
#include <cstdio>
using namespace std;
typedef struct number Number;
ifstream fin("pprime.in");
ofstream fout("pprime.out");
int MAXN = 100000000;
unsigned short bits[2000000] = {};
vector<int> primes;
vector<int> all;
int a, b;
short getBit(int atPos)
{
int whichNumber = (atPos-1) / 16;
int atWhichPosInTheNumber = (atPos-1) % 16;
return ((bits[whichNumber] & (1 << atWhichPosInTheNumber)) >> atWhichPosInTheNumber);
}
void setBit(int atPos)
{
int whichNumber = (atPos-1) / 16;
int atWhichPosInTheNumber = (atPos-1) % 16;
int old = bits[whichNumber];
bits[whichNumber] = bits[whichNumber] | (1 << atWhichPosInTheNumber);
}
void calcSieve()
{
for(int i = 2; i < MAXN; ++i)
{
if(getBit(i) == 0)
{
for(int j = 2*i; j <= (MAXN); j += i)
{
setBit(j);
}
primes.push_back(i);
}
}
}
int toInt(list<short> integer)
{
int number = 0;
while(!integer.empty())
{
int current = integer.front();
integer.pop_front();
number = number * 10 + current;
}
return number;
}
void toString(int number, char buffer[])
{
int i = 0;
while(number != 0)
{
buffer[i] = number % 10 + '0';
number /= 10;
}
}
void DFS(list<short> integer, int N, int atLeast)
{
if(integer.size() > N)
{
return;
}
if(!(integer.size() > 0 && (integer.front() == 0 || integer.back() % 2 == 0)) && atLeast <= integer.size())
{
int toI = toInt(integer);
if(toI <= b) all.push_back(toInt(integer));
}
for(short i = 0; i <= 9; ++i)
{
integer.push_back(i);
integer.push_front(i);
DFS(integer, N, atLeast);
integer.pop_back();
integer.pop_front();
}
}
bool isPrime(int number)
{
for(int i = 0; i < primes.size() && number > primes[i]; ++i)
{
if(number % primes[i] == 0) return false;
}
return true;
}
int main()
{
int t = clock();
ios::sync_with_stdio(false);
fin >> a >> b;
MAXN = min(MAXN, b);
int N = (int)log10(b) + 1;
int atLeast = (int)log10(a) + 1;
for(short i = 0; i <= 9; ++i)
{
list<short> current;
current.push_back(i);
DFS(current, N, atLeast);
}
list<short> empty;
DFS(empty, N, atLeast);
sort(all.begin(), all.end());
//calcSieve
calcSieve();
//
string output = "";
int ends = clock() - t;
cout<<"Exexution time: "<<((float)ends)/CLOCKS_PER_SEC<<" seconds";
cout<<"\nsize: "<<all.size()<<endl;
FILE* pFile;
pFile = fopen("pprime.out", "w");
for(int i = 0; i < all.size(); ++i)
{
if(all[i] < a) continue;
else if(all[i] > b) break;
if(isPrime(all[i]))
{
char buffer[50];
//toString(all[i], buffer);
int c = all[i];
log10(c);
buffer[3] = 2;
//buffer[(int)log10(all[i])+1] = '\n';
//buffer[(int)log10(all[i])+2] = '\0';
//fputs(buffer, pFile);
}
}
ends = clock() - t;
cout<<"\nExexution time: "<<((float)ends)/CLOCKS_PER_SEC<<" seconds";
ends = clock() - t;
cout<<"\nExexution time: "<<((float)ends)/CLOCKS_PER_SEC<<" seconds";
fclose(pFile);
//fout<<output;
return 0;
}
I think you've done this backwards. It seems odd to generate all the possible palindromes (if that's what DFS actually does... that function confuses me) and then check which of them are prime. Especially since you have to generate the primes anyway.
The other thing is that you are doing a linear search in isPrime, which is not taking advantage of the fact that the array is sorted. Use a binary search instead.
And also, using list instead of vector for your DFS function will hurt your runtime. Try using a deque.
Now, all that said, I think that you should do this the other way around. There are a huge number of palindromes that won't be prime. What's the point in generating them? A simple stack is all you need to check if a number is a palindrome. Like this:
bool IsPalindrome( unsigned int val )
{
int digits[10];
int multiplier = 1;
int *d = digits;
// Add half of number's digits to a stack
while( multiplier < val ) {
*d++ = val % 10;
val /= 10;
multiplier *= 10;
}
// Adjust for odd-length palindrome
if( val * 10 < multiplier ) --d;
// Check remaining digits
while( val != 0 ) {
if(*(--d) != val % 10) return false;
val /= 10;
}
return true;
}
This avoids the need to call log10 at all, as well as eliminates all that palindrome generation. The sieve is pretty fast, and after that you'll only have a few thousand primes to test, most of which will not be palindromes.
Now your whole program becomes something like this:
calcSieve();
for( vector<int>::iterator it = primes.begin(); it != primes.end(); it++ ) {
if( IsPalindrome(*it) ) cout << *it << "\n";
}
One other thing to point out. Two things actually:
int MAXN = 100000000;
unsigned short bits[2000000] = {};
bits is too short to represent 100 million flags.
bits is uninitialised.
To address both these issues, try:
unsigned short bits[1 + MAXN / 16] = { 0 };

C++ get each digit in int

I have an integer:
int iNums = 12476;
And now I want to get each digit from iNums as integer. Something like:
foreach(iNum in iNums){
printf("%i-", iNum);
}
So the output would be: "1-2-4-7-6-".
But i actually need each digit as int not as char.
Thanks for help.
void print_each_digit(int x)
{
if(x >= 10)
print_each_digit(x / 10);
int digit = x % 10;
std::cout << digit << '\n';
}
Convert it to string, then iterate over the characters. For the conversion you may use std::ostringstream, e.g.:
int iNums = 12476;
std::ostringstream os;
os << iNums;
std::string digits = os.str();
Btw the generally used term (for what you call "number") is "digit" - please use it, as it makes the title of your post much more understandable :-)
Here is a more generic though recursive solution that yields a vector of digits:
void collect_digits(std::vector<int>& digits, unsigned long num) {
if (num > 9) {
collect_digits(digits, num / 10);
}
digits.push_back(num % 10);
}
Being that there are is a relatively small number of digits, the recursion is neatly bounded.
Here is the way to perform this action, but by this you will get in reverse order.
int num;
short temp = 0;
cin>>num;
while(num!=0){
temp = num%10;
//here you will get its element one by one but in reverse order
//you can perform your action here.
num /= 10;
}
I don't test it just write what is in my head. excuse for any syntax error
Here is online ideone demo
vector <int> v;
int i = ....
while(i != 0 ){
cout << i%10 << " - "; // reverse order
v.push_back(i%10);
i = i/10;
}
cout << endl;
for(int i=v.size()-1; i>=0; i--){
cout << v[i] << " - "; // linear
}
To get digit at "pos" position (starting at position 1 as Least Significant Digit (LSD)):
digit = (int)(number/pow(10,(pos-1))) % 10;
Example: number = 57820 --> pos = 4 --> digit = 7
To sequentially get digits:
int num_digits = floor( log10(abs(number?number:1)) + 1 );
for(; num_digits; num_digits--, number/=10) {
std::cout << number % 10 << " ";
}
Example: number = 57820 --> output: 0 2 8 7 5
You can do it with this function:
void printDigits(int number) {
if (number < 0) { // Handling negative number
printf('-');
number *= -1;
}
if (number == 0) { // Handling zero
printf('0');
}
while (number > 0) { // Printing the number
printf("%d-", number % 10);
number /= 10;
}
}
Drawn from D.Shawley's answer, can go a bit further to completely answer by outputing the result:
void stream_digits(std::ostream& output, int num, const std::string& delimiter = "")
{
if (num) {
stream_digits(output, num/10, delimiter);
output << static_cast<char>('0' + (num % 10)) << delimiter;
}
}
void splitDigits()
{
int num = 12476;
stream_digits(std::cout, num, "-");
std::cout << std::endl;
}
I don't know if this is faster or slower or worthless, but this would be an alternative:
int iNums = 12476;
string numString;
stringstream ss;
ss << iNums;
numString = ss.str();
for (int i = 0; i < numString.length(); i++) {
int myInt = static_cast<int>(numString[i] - '0'); // '0' = 48
printf("%i-", myInt);
}
I point this out as iNums alludes to possibly being user input, and if the user input was a string in the first place you wouldn't need to go through the hassle of converting the int to a string.
(to_string could be used in c++11)
I know this is an old post, but all of these answers were unacceptable to me, so I wrote my own!
My purpose was for rendering a number to a screen, hence the function names.
void RenderNumber(int to_print)
{
if (to_print < 0)
{
RenderMinusSign()
RenderNumber(-to_print);
}
else
{
int digits = 1; // Assume if 0 is entered we want to print 0 (i.e. minimum of 1 digit)
int max = 10;
while (to_print >= max) // find how many digits the number is
{
max *= 10;
digits ++;
}
for (int i = 0; i < digits; i++) // loop through each digit
{
max /= 10;
int num = to_print / max; // isolate first digit
to_print -= num * max; // subtract first digit from number
RenderDigit(num);
}
}
}
Based on #Abyx's answer, but uses div so that only 1 division is done per digit.
#include <cstdlib>
#include <iostream>
void print_each_digit(int x)
{
div_t q = div(x, 10);
if (q.quot)
print_each_digit(q.quot);
std::cout << q.rem << '-';
}
int main()
{
print_each_digit(12476);
std::cout << std::endl;
return 0;
}
Output:
1-2-4-7-6-
N.B. Only works for non-negative ints.
My solution:
void getSumDigits(int n) {
std::vector<int> int_to_vec;
while(n>0)
{
int_to_vec.push_back(n%10);
n=n/10;
}
int sum;
for(int i=0;i<int_to_vec.size();i++)
{
sum+=int_to_vec.at(i);
}
std::cout << sum << ' ';
}
The answer I've used is this simple function:
int getDigit(int n, int position) {
return (n%(int)pow(10, position) - (n % (int)pow(10, position-1))) / (int)pow(10, position-1);
}
Hope someone finds this helpful!
// Online C++ compiler to run C++ program online
#include <iostream>
#include <cmath>
int main() {
int iNums = 123458;
// int iNumsSize = 5;
int iNumsSize = trunc(log10(iNums)) + 1; // Find length of int value
for (int i=iNumsSize-1; i>=0; i--) {
int y = pow(10, i);
// The pow() function returns the result of the first argument raised to
the power of the second argument.
int z = iNums/y;
int x2 = iNums / (y * 10);
printf("%d ",z - x2*10 ); // Print Values
}
return 0;
}
You can do it using a while loop and the modulo operators.
It just gives the digits in the revese order.
int main() {
int iNums = 12476;
int iNum = 0;
while(iNums > 0) {
iNum = iNums % 10;
cout << iNum;
iNums = iNums / 10;
}
}
int a;
cout << "Enter a number: ";
cin >> a;
while (a > 0) {
cout << a % 10 << endl;
a = a / 10;
}
int iNums = 12345;
int iNumsSize = 5;
for (int i=iNumsSize-1; i>=0; i--) {
int y = pow(10, i);
int z = iNums/y;
int x2 = iNums / (y * 10);
printf("%d-",z - x2*10 );
}