I have problem with such error: Run-Time Check Failure #2 - Stack around the variable 'numb' was corrupted.
It appears at the last bracket of such function:
int problem20()
{
int res = 0, i;
int numb[160];
for(i = 0; i < 160; i++)
numb[i] = 0;
numb[0] = 1;
for(i = 1; i < 100; i++)
{
multiply(numb, i, numb, 160);
}
for(i = 0; i < 160; i++)
res += numb[i];
return res;
}
EDIT:
void multiply(int* a1, int a2, int* res, int l)
{
int temp, i, m = a2, k;
for(k = 0; m > 0; k++)
m /= 10;
int *result = new int[l + k];
for(i = 0, temp = 0; i < l; i++)
{
result[i] = a1[i] * a2 + temp;
temp = result[i] / 10;
result[i] %= 10;
}
for(i = l; i < l + k; i++)
{
result[i] = temp % 10;
temp /= 10;
}
memcpy(res, result, sizeof(int) * (l + k));
delete[] result;
}
function miltiply just multiply numb by i and give result to the third argument. This function is ok, it was tested earlier.
Your problem is that you pass numb as the res argument for the multiply function. The multiply function creates an array that has size l + k and then tries to copy it to the numb array with size l, this means that you are going out of the bounds of the numb array which in turn triggers this problem.
I would suggest turning the int* arguments to references to std::vector in order to avoid the need to manually allocate a temporary array.
Related
Firstly I created my two dimensional array, then I translated it to one dimensional array and I bubble sorted the 1D array, but after I didn't find the pattern to bring it back to 2D array diagonally sorted.
#include<iostream>
#include<iomanip>
const int r = 10;
const int c = 10;
const int lim = r * c;
int A[r][c] = { 0 };
int B[lim];
using namespace std;
void generatearray(int A[][], int r, int c){
srand(time(NULL));
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
A[i][j] = rand() % lim;
}
}
}
void transformingto1Darray(int A[r][c], int b[lim]){
int p = 0;
for (int m = 0; m < r; m++){
for (int n = 0; n < c; n++){
B[p] = A[m][n];
p++;
}
}
}
void sorting1Darray(int B[][]){
int temp = 0;
for (int k = 0; k < lim - 1; k++){
for (int i = 0; i < lim - 1; i++)
if (B[i] > B[i + 1]){
temp = B[i];
B[i] = B[i + 1];
B[i + 1] = temp;
}
}
}
void sortingdiagonally2Darray(int A[][], int B[]){
int main{
generatearray(A);
transformingto1Darray(A, B);
sorting1Darray(B);
sortingdiagonally2Darray(A, B);
return 0;
}
It's a bit of a wonky solution but it dose work. Because of the way multidimensional indexing works the value in B[i] will be equal to the value in A[0][i].
In your case you want something like this in your sortingdiagonally2Darray function.
for (int i = 0; i > r * c; i++) {
A[0][i] = B[i];
}
This works because under the hood arrays are just pointers. B[x] is syntactic sugar for *(B + x) and A[0][x] will equate to *(*(A + 0) + x) because it's a pointer to a pointer (hence the double star/double brackets).
I am trying to use radix sort to sort file contain social security and date of birth the format looks like this "###-##-####,#######.I have to apply radix sort on each fields according to command line switch. I have a radix sort that is work for int array and i am trying to modify the code for string type array but i am not sure how to accomplish this. I did a quick sort for string type by comparing strings and pivot and that is work fine however for radix sort I am not if I can do this with string type or I have to convert the string to integer. I have tried to use "atoi" to convert to integer but I am not sure how to correctly do this if I have to.
string getMax(string arr[], int n){
string max = arr[0];
for (int i = 1; i < n; i++){
if (arr[i]>max)
max = arr[i];
}
return max;
}
void countSort(string a[], int size, int k){
string *b = NULL; int *c = NULL;
b = new string[size];
c = new int[k];
for (int i = 0; i <k; i++){
c[i] = 0;
//cout << c[i] << "\n";
}
for (int j = 0; j <size; j++){
c[(a[j]/k)%10]++; //a[j] is a string
//cout << c[a[j]] << endl;
}
for (int f = 1; f <10; f++){
c[f] += c[f - 1];
}
for (int r = size - 1; r >= 0; r--){
b[c[(a[r] / k) % 10] - 1] = a[r];
c[(a[r] / k) % 10]--;
}
for (int l = 0; l < size; l++){
a[l] = b[l];
}
}
void radixSort(string b[], int r){
string max = getMax(b, r);
for (int digit = 1; max / digit > 0; digit *= 10){
countSort(b, r, digit);
}
};
I didn't try, but I think you can do radix sort for string.
Calculate the length of the longest string in the array to sort.
Do radix sort just like for integers. Do sorting using each characters in the string.
If a string is shorter than another and there is no character in the "digit", consider its value as -65536 (or a smaller value than any other characters).
UPDATE: I tested my idea and it seems working.
#include <cstdio>
#include <string>
using std::string;
size_t getMax(string arr[], int n){
size_t max = arr[0].size();
for (int i = 1; i < n; i++){
if (arr[i].size()>max)
max = arr[i].size();
}
return max;
}
void countSort(string a[], int size, size_t k){
string *b = NULL; int *c = NULL;
b = new string[size];
c = new int[257];
for (int i = 0; i <257; i++){
c[i] = 0;
//cout << c[i] << "\n";
}
for (int j = 0; j <size; j++){
c[k < a[j].size() ? (int)(unsigned char)a[j][k] + 1 : 0]++; //a[j] is a string
//cout << c[a[j]] << endl;
}
for (int f = 1; f <257; f++){
c[f] += c[f - 1];
}
for (int r = size - 1; r >= 0; r--){
b[c[k < a[r].size() ? (int)(unsigned char)a[r][k] + 1 : 0] - 1] = a[r];
c[k < a[r].size() ? (int)(unsigned char)a[r][k] + 1 : 0]--;
}
for (int l = 0; l < size; l++){
a[l] = b[l];
}
// avold memory leak
delete[] b;
delete[] c;
}
void radixSort(string b[], int r){
size_t max = getMax(b, r);
for (size_t digit = max; digit > 0; digit--){ // size_t is unsigned, so avoid using digit >= 0, which is always true
countSort(b, r, digit - 1);
}
}
int main(void) {
string data[] = {
"aaaba",
"dfjasdlifjai",
"jiifjeogiejogp",
"aabaaaa",
"gsgj",
"gerph",
"aaaaaaa",
"htjltjlrth",
"joasdjfisdjfdo",
"hthe",
"aaaaaba",
"jrykpjl",
"hkoptjltp",
"aaaaaa",
"lprrjt"
};
puts("before sorting:");
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
printf(" %s\n", data[i].c_str());
}
radixSort(data, (int)(sizeof(data) / sizeof(data[0])));
puts("after sorting:");
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
printf(" %s\n", data[i].c_str());
}
return 0;
}
I am trying to achieve the fftshift function (from MATLAB) in c++ with for loop and it's really time-consuming. here is my code:
const int a = 3;
const int b = 4;
const int c = 5;
int i, j, k;
int aa = a / 2;
int bb = b / 2;
int cc = c / 2;
double ***te, ***tempa;
te = new double **[a];
tempa = new double **[a];
for (i = 0; i < a; i++)
{
te[i] = new double *[b];
tempa[i] = new double *[b];
for (j = 0; j < b; j++)
{
te[i][j] = new double [c];
tempa[i][j] = new double [c];
for (k = 0; k < c; k++)
{
te[i][j][k] = i + j+k;
}
}
}
/*for the row*/
if (c % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < cc; k++)
{
tempa[i][j][k] = te[i][j][k + cc + 1];
tempa[i][j][k + cc] = te[i][j][k];
tempa[i][j][c - 1] = te[i][j][cc];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < cc; k++)
{
tempa[i][j][k] = te[i][j][k + cc];
tempa[i][j][k + cc] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the column*/
if (b % 2 == 1)
{
for (i = 0; i < a; i++)
{
for (j = 0; j < bb; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + bb + 1][k];
tempa[i][j + bb][k] = te[i][j][k];
tempa[i][b - 1][k] = te[i][bb][k];
}
}
}
}
else
{
for (i = 0; i < a; i++)
{
for (j = 0; j < bb; j++)
{
for (k = 0; k < c; k++)
{
tempa[i][j][k] = te[i][j + bb][k];
tempa[i][j + bb][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
te[i][j][k] = tempa[i][j][k];
}
}
}
/*for the third dimension*/
if (a % 2 == 1)
{
for ( i = 0; i < aa; i++)
{
for (j = 0; j < b; j++)
{
for ( k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + aa + 1][j][k];
tempa[i + aa][j][k] = te[i][j][k];
tempa[a - 1][j][k] = te[aa][j][k];
}
}
}
}
else
{
for (i = 0; i < aa; i++)
{
for ( j = 0; j < b; j++)
{
for ( k = 0; k < c; k++)
{
tempa[i][j][k] = te[i + aa][j][k];
tempa[i + aa][j][k] = te[i][j][k];
}
}
}
}
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
cout << te[i][j][k] << ' ';
}
cout << endl;
}
cout << "\n";
}
cout << "and then" << endl;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
for (k = 0; k < c; k++)
{
cout << tempa[i][j][k] << ' ';
}
cout << endl;
}
cout << "\n";
}
now I want to rewrite it with memmove to improve the running efficiency.
For the 3rd dimension, I use:
memmove(tempa, te + aa, sizeof(double)*(a - aa));
memmove(tempa + aa+1, te, sizeof(double)* aa);
this code can works well with 1d and 2d array, but doesn't work for the 3d array. Also, I do not know how to move the column and row elements with memmove. Anyone can help me with all of these? thanks so much!!
Now I have modified the code as below:
double ***te, ***tempa1,***tempa2, ***tempa3;
te = new double **[a];
tempa1 = new double **[a];
tempa2 = new double **[a];
tempa3 = new double **[a];
for (i = 0; i < a; i++)
{
te[i] = new double *[b];
tempa1[i] = new double *[b];
tempa2[i] = new double *[b];
tempa3[i] = new double *[b];
for (j = 0; j < b; j++)
{
te[i][j] = new double [c];
tempa1[i][j] = new double [c];
tempa2[i][j] = new double [c];
tempa3[i][j] = new double [c];
for (k = 0; k < c; k++)
{
te[i][j][k] = i + j+k;
}
}
}
/*for the third dimension*/
memmove(tempa1, te + (a-aa), sizeof(double**)*aa);
memmove(tempa1 + aa, te, sizeof(double**)* (a-aa));
//memmove(te, tempa, sizeof(double)*a);
/*for the row*/
for (i = 0; i < a; i++)
{
memmove(tempa2[i], tempa1[i] + (b - bb), sizeof(double*)*bb);
memmove(tempa2[i] + bb, tempa1[i], sizeof(double*)*(b - bb));
}
/*for the column*/
for (j = 0; i < a; i++)
{
for (k = 0; j < b; j++)
{
memmove(tempa3[i][j], tempa2[i][j] + (c - cc), sizeof(double)*cc);
memmove(tempa3[i][j] + cc, tempa2[i][j], sizeof(double)*(c-cc));
}
}
but the problem is that I define too much new dynamic arrays and also the results for tempa3 are incorrect. could anyone give some suggestions?
I believe you want something like that:
memmove(tempa, te + (a - aa), sizeof(double**) * aa);
memmove(tempa + aa, te, sizeof(double**) * (a - aa));
or
memmove(tempa, te + aa, sizeof(double**) * (a - aa));
memmove(tempa + (a - aa), te, sizeof(double**) * aa);
depending on whether you want to swap the first half "rounded up or down" (I assume you want it rounded up, it's the first version then).
I don't really like your code's design though:
First and foremost, avoid dynamic allocation and use std::vector or std::array when possible.
You could argue it would prevent you from safely using memmove instead of swap for the first dimensions (well, it should work, but I'm not 100% sure it isn't implementation defined) but I don't think that would improve that much the efficiency.
Besides, if you want to have a N-dimensional array, I usually prefer avoiding "chaining pointers" (although with your algorithm, you can actually use this structure, so it's not that bad).
For instance, if you're adamant about dynamically allocating your array with new, you might use something like that instead to reduce memory usage (the difference might be neglectible though; it's also probably slightly faster but again, probably neglectible):
#include <cstddef>
#include <iostream>
typedef std::size_t index_t;
constexpr index_t width = 3;
constexpr index_t height = 4;
constexpr index_t depth = 5;
// the cells (i, j, k) and (i, j, k+1) are adjacent in memory
// the rows (i, j, _) and (i, j+1, _) are adjacent in memory
// the "slices" (i, _, _) and (i+1, _, _) are adjacent in memory
constexpr index_t cell_index(index_t i, index_t j, index_t k) {
return (i * height + j) * depth + k;
}
int main() {
int* array = new int[width * height * depth]();
for( index_t i = 0 ; i < width ; ++i )
for( index_t j = 0 ; j < height ; ++j )
for( index_t k = 0 ; k < depth ; ++k ) {
// do something on the cell (i, j, k)
array[cell_index(i, j, k)] = i + j + k;
std::cout << array[cell_index(i, j, k)] << ' ';
}
std::cout << '\n';
// alternatively you can do this:
//*
for( index_t index = 0 ; index < width * height * depth ; ++index) {
index_t i = index / (height * depth);
index_t j = (index / depth) % height;
index_t k = index % depth;
array[index] = i + j + k;
std::cout << array[index] << ' ';
}
std::cout << '\n';
//*/
delete[] array;
}
The difference is the organization in memory. Here you have a big block of 60*sizeof(int) bytes (usually 240 or 480 bytes), whereas with your method you would have:
- 1 block of 3*sizeof(int**) bytes
- 3 blocks of 4*sizeof(int*) bytes
- 12 blocks of 5*sizeof(int) bytes
(120 more bytes on a 64 bit architecture, two additional indirections for each cell access, and more code for allocating/deallocating all that memory)
Granted, you can't do array[i][j][k] anymore, but still...
The same stands with vectors (you can either make an std::vector<std::vector<std::vector<int>>> or a std::vector<int>)
There is also a bit too much code repetition: your algorithm basically swaps the two halves of your table three times (once for each dimension), but you rewrote 3 times the same thing with a few differences.
There is also too much memory allocation/copy (your algorithm works and can exploit the structure of array of pointers by simply swapping pointers to swap whole rows/slices, in that specific case, you can exploit this data structure to avoid copies with your algorithm... but you don't)
You should choose more explicit variable names, that helps. For instance use width, height, depth instead of a, b, c.
For instance, here is an implementation with vectors (I didn't know matlab's fftshift function though, but according to your code and this page, I assume it's basically "swapping the corners"):
(also, compile with -std=c++11)
#include <cstddef>
#include <iostream>
#include <vector>
#include <algorithm>
typedef std::size_t index_t;
typedef double element_t;
typedef std::vector<element_t> row_t;
typedef std::vector<row_t> slice_t;
typedef std::vector<slice_t> array_3d_t;
// for one dimension
// you might overload this for a std::vector<double>& and use memmove
// as you originally wanted to do here
template<class T>
void fftshift_dimension(std::vector<T>& row)
{
using std::swap;
const index_t size = row.size();
if(size <= 1)
return;
const index_t halved_size = size / 2;
// swap the two halves
for(index_t i = 0, j = size - halved_size ; i < halved_size ; ++i, ++j)
swap(row[i], row[j]);
// if the size is odd, rotate the right part
if(size % 2)
{
swap(row[halved_size], row[size - 1]);
const index_t n = size - 2;
for(index_t i = halved_size ; i < n ; ++i)
swap(row[i], row[i + 1]);
}
}
// base case
template<class T>
void fftshift(std::vector<T>& array) {
fftshift_dimension(array);
}
// reduce the problem for a dimension N+1 to a dimension N
template<class T>
void fftshift(std::vector<std::vector<T>>& array) {
fftshift_dimension(array);
for(auto& slice : array)
fftshift(slice);
}
// overloads operator<< to print a 3-dimensional array
std::ostream& operator<<(std::ostream& output, const array_3d_t& input) {
const index_t width = input.size();
for(index_t i = 0; i < width ; i++)
{
const index_t height = input[i].size();
for(index_t j = 0; j < height ; j++)
{
const index_t depth = input[i][j].size();
for(index_t k = 0; k < depth; k++)
output << input[i][j][k] << ' ';
output << '\n';
}
output << '\n';
}
return output;
}
int main()
{
constexpr index_t width = 3;
constexpr index_t height = 4;
constexpr index_t depth = 5;
array_3d_t input(width, slice_t(height, row_t(depth)));
// initialization
for(index_t i = 0 ; i < width ; ++i)
for(index_t j = 0 ; j < height ; ++j)
for(index_t k = 0 ; k < depth ; ++k)
input[i][j][k] = i + j + k;
std::cout << input;
// in place fftshift
fftshift(input);
std::cout << "and then" << '\n' << input;
}
live example
You could probably make a slightly more efficient algorithm by avoiding to swap multiple times the same cell and/or using memmove, but I think it's already fast enough for many uses (on my machine fftshift takes roughly 130ms for a 1000x1000x100 table).
This is for an assignment in an algorithm class. I understand and agree that using a vector would simplify things, but that isn't an option.
The code for the Mergesort / merge algorithm can't be modified either.
I need to run the merge sort as follows:
starting from 100 all the way to 1000, increments of 100. For each increment I run it 5 times, for each of these times I run it 1000 times.
That being said - everything works fine until my loop reaches 700 and crashes with the error: "Unhandled exception at 0x75612F71 in msdebug.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x010672F4."
Here is my code:
int const size = 6;
int const size2 = 1001;
int const times = 6;
int const interval = 11;
void merge(int arr[], int p, int q, int r)
{
int n1 = q - p + 1;
int n2 = r - q;
int * L = new int[n1 + 1];
int * R = new int[n2 + 1]; // line giving the error after 700
for (int i = 1; i <= n1; i++)
{
L[i] = arr[p + i - 1];
}
for (int j = 1; j <= n2; j++)
{
R[j] = arr[q + j];
}
L[n1 + 1] = 32768;
R[n2 + 1] = 32768;
int i, j;
i = j = 1;
for (int k = p; k <= r; k++)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
}
}
void mergeSort(int arr[], int p, int r)
{
int q;
if (p < r)
{
q = ((p + r) / 2);
mergeSort(arr, p, q);
mergeSort(arr, (q + 1), r);
merge(arr, p, q, r);
}
}
void copyArray(int original[][size2], int copy[], int row, int finish)
{
int i = 1;
while (i <= finish)
{
copy[i] = original[row][i];
i++;
}
}
void copyOneD(int orig[], int cop[])
{
for (int i = 1; i < size2; i++)
{
cop[i] = orig[i];
}
}
int main()
{
struct timeval;
clock_t start, end;
srand(time(NULL));
int arr[size][size2];
int arr2[size2];
int arrCopy[size2];
double tMergeSort[times][interval];
double avgTmergeSort[11];
/*for (int i = 1; i < (size2); i++)
{
arr2[i] = rand();
}*/
for (int i = 1; i < size; i++)
{
for (int j = 1; j < size2; j++)
{
arr[i][j] = rand();
}
}
for (int x = 100; x <= 1000; x = x + 100) //This loop crashes >=700
{
for (int r = 1; r <= 5; r++)
{
copyArray(arr, arr2, r, 1001);
for (int k = 0; k < 1000; k++)
{
copyOneD(arr2, arrCopy);
mergeSort(arrCopy, 1, x);
}
}
}
return 0;
}
You can ignore the code and the arrays. Those functions work fine.
Everything works fine until I set 'x <= 700' or higher and then it crashes.
I had a theory that maybe the computer runs out of memory for the pointers in the merge algorithm but when I tried to use delete it also crashed.
Any help is appreciated and suggestions as well.
Thanks
I was researching counting sort and decided to try an algorithm i found online. Though, it doesn't seem to actually sort my array.
void countSort2(int arr[], int n, int exp)
{
int *output = new int[n]; // output array
int i, count[10] = {0};
// Store count of occurrences in count[]
for (i = 0; i < n; i++)
count[ (arr[i]/exp)%10 ]++;
// Change count[i] so that count[i] now contains actual position of
// this digit in output[]
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
// Build the output array
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%10 ] - 1] = arr[i];
count[ (arr[i]/exp)%10 ]--;
}
// Copy the output array to arr[], so that arr[] now
// contains sorted numbers according to curent digit
for (i = 0; i < n; i++)
arr[i] = output[i];
}
int main()
{
int b[10] = {4,3,2,1,6,7,8,9,7,6};
countSort2(b,10,10);
int i = 0;
while(i<10)
{
cout<<b[i]<<endl;
i++;
}
When the array is printed out, I get: "4,3,2,1,6,7,8,9,7,6". Am I calling the function wrong?
This is how you call the method [1]..
10 is the number of elements...
int main()
{
int b[10] = {14,23,22,11,66,67,58,49,17,16};
countSort2(b,10,1);
countSort2(b,10,10);
int i = 0;
while(i<10)
{
cout<<b[i]<<endl;
i++;
}
return 0;
}
This is a radix sort that sorts an array by a decimal digit. The sort is done from least significant digit to most significant digit. This means a series of calls with exp = 1, 10, 100, 1000, 10000, ... .
Here is an example of a radix sort that sorts an array of 64 bit unsigned integers by the bytes in the integers, from least significant to most significant. In this example, the temporary array is passed as a parameter to RadixSort():
typedef unsigned __int64 UI64;
typedef unsigned __int64 * PUI64;
PUI64 RadixSort(PUI64 pData, PUI64 pTemp, size_t count)
{
size_t mIndex[8][256] = {0}; // index matrix
PUI64 pDst, pSrc, pTmp;
size_t i,j,m,n;
UI64 u;
for(i = 0; i < count; i++){ // generate histograms
u = pData[i];
for(j = 0; j < 8; j++){
mIndex[j][(size_t)(u & 0xff)]++;
u >>= 8;
}
}
for(j = 0; j < 8; j++){ // convert to indices
n = 0;
for(i = 0; i < 256; i++){
m = mIndex[j][i];
mIndex[j][i] = n;
n += m;
}
}
pDst = pTemp; // radix sort
pSrc = pData;
for(j = 0; j < 8; j++){
for(i = 0; i < count; i++){
u = pSrc[i];
m = (size_t)(u >> (j<<3)) & 0xff;
pDst[mIndex[j][m]++] = u;
}
pTmp = pSrc;
pSrc = pDst;
pDst = pTmp;
}
return(pSrc);
}