unable to change value of integer after looping, C++ - c++

At the start of my program I declare the variables i and j.
int i, j;
In the course of execution, I use the variable names i and j as a oop index variables too. I realize this is probably not the best choice in terms of clarity, but as this is a toy project I thought it wouldn't matter.
The problem is, after the following loop that prints the contents of an array to a txt file, i == N == 29:
ofstream a_file("2d_array.txt");
for (int i = 0; i<N; ++i) {
for (int j = 0; j<N; ++j)
a_file << m[i][j] << ' ';
a_file << endl;
}
When I try to use i again later in the program:
for (int num_slices_processed = h + 1; num_slices_processed < N;
num_slices_processed++){
i = 0;
j = num_slices_processed;
...
i remains set to 29, even after the line that should set it to 0. j is set correctly though. What is happening here?
Here is all the code up to the problem section:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int smallest(int x, int y, int z);
bool basesMatch(char b1, char b2);
int main() {
const int N = 29;
int h, l, mm;
int i, j;
l = 10;
mm = 2;
h = 5;
int m[N][N];
//initialize m
for (int i = 0; i < N; i++){
for (int j = i; j < N; j++) {
if (j-i <= h)
m[i][j] = 0;
}
}
ofstream a_file("2d_array.txt");
for (int i = 0; i<N; ++i) {
for (int j = 0; j<N; ++j)
a_file << m[i][j] << ' ';
a_file << endl;
}
for (int num_slices_processed = h + 1; num_slices_processed < N; num_slices_processed++){
//while j is in bounds, ie j < N. This fills in one diagonal slice of m from L->R top -> bottom.
i = 0; //************ i is not being set here
j = num_slices_processed;
while (j < N) {
if (basesMatch(seq[i], seq[j])) {
t = m[i + 1][j - 1];
m[i][j] = m[i + 1][j - 1];
}
else {//bases don't match
m[i][j] = smallest(m[i + 1][j] + 1, m[i][j - 1] + 1, m[i + 1][j - 1] + 1);
}
i++;
j++;
}
}

Check to see if it even enters the loop. num_slices_processed could be null or already < N, so you are never hitting the assignment statement.

Related

Counting sort not sorting correctly

I have written this counting sort algorithm, but am not sure why it isn't working... Could anyone check and give me a few pointers on what to fix? Thanks!
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 10; k > 0; --k) {
C[k] = C[k] + C[k + 1];
}
int B[10];
for (int l = 0; l < 10; ++l) {
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}
The problem is in the third loop. You iterate only through 10 elements of the array C.
You had created small mistake in the code.....
#include <iostream>
using namespace std;
int main(){
int arr[10] = {1434, 1415, 1217, 4218, 3618, 176, 1021, 3785, 1891, 1522};
int C[4219];
for (int i = 0; i < 4219; ++i) {
C[i] = 0;
}
for (int j = 0; j < 10; ++j) {
C[arr[j]] = C[arr[j]] + 1;
}
for (int k = 1; k < 4219; ++k) { // mistake
C[k] = C[k] + C[k - 1];
}
int B[10];
for (int l = 9; l >=0; --l) { // suggestion
B[C[arr[l]] - 1] = arr[l];
C[arr[l]] = C[arr[l]] - 1;
}
for (int m = 0; m < 10; ++m) {
cout << B[m] << " ";
}
return 0;
}
Beside that I would like to give you one suggestion that in the loop traverse from right to left as it will maintain the stability of the sort..
Stability means suppose if array has two or more same element then in the stable sort,element which is before in unsorted array will occur first in sorted array.

Counting Sort in C++

I am trying to implement the Counting Sort in C++ without creating a function. This is the code that I've written so far, but the program doesn't return me any values. It doesn't give me any errors either. Therefore, what is wrong?
#include <iostream>
using namespace std;
int main()
{
int A[100], B[100], C[100], i, j, k = 0, n;
cin >> n;
for (i = 0; i < n; ++i)
{
cin >> A[i];
}
for (i = 0; i < n; ++i)
{
if (A[i] > k)
{
k = A[i];
}
}
for (i = 0; i < k + 1; ++i)
{
C[i] = 0;
}
for (j = 0; j < n; ++j)
{
C[A[j]]++;
}
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
for (i = 0; i < n; ++i)
{
cout << B[i] << " ";
}
return 0;
}
It looks like you're on the right track. You take input into A, find the largest value you'll be dealing with and then make sure you zero out that many values in your C array. But that's when things start to go wrong. You then do:
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
That first loop will always go out of bounds on the first iteration (C[i-1] when i=0 will be undefined behavior), but even if it didn't I'm not sure what you have in mind here. Or in the loop after that for that matter.
Instead, if I were you, I'd create an indx variable to keep track of which index I'm next going to insert a number to (how many numbers I've inserted so far), and then I'd loop over C and for each value in C, I'd loop that many times and insert that many values of that index. My explanation may sound a little wordy, but that'd look like:
int indx = 0;
for(int x = 0; x <= k; x++) {
for(int y = 0; y < C[x]; y++) {
B[indx++] = x;
}
}
If you replace the two loops above with this one, then everything should work as expected.
See a live example here: ideone

mtrix chain multiplication print the sequence of the mattrices

I have written code for matrix chain multiplication in dynamic programming in c++.
there is an error in the recursive call for printing the correct parenthesization of the matrices. I am taking input from text file and giving output on a text file. please help..
#include <iostream>
#include <fstream>
#include <limits.h>
using namespace std;
int * MatrixChainOrder(int p[], int n)
{
static int m[100][100];
static int s[100][100];
int j, q;
int min = INT_MAX;
for (int i = 1; i <= n; i++)
m[i][i] = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
j = i + L - 1;
m[i][j] = min;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return (*s);
}
void Print(int *s, int i, int j)
{
ofstream outfile("output.text");
if (i == j)
{
outfile << "a1";
}
else
outfile << "(";
{
Print(*s, i, s[i][j]);
Print(*s, s[i][j] + 1, j);
outfile << ")";
}
outfile.close();
}
int main()
{
int arr[100];
int num, i = 0;
ifstream infile("input.text");
while (infile)
{
infile >> num;
arr[i] = num;
i++;
}
i = i - 1;
infile.close();
Print(MatrixChainOrder(arr, i - 1), 0, i - 1);
return 0;
}
In C++ it is better to use std::vector for arrays. Aside from that, you can't mix pointers and arrays like that because the compiler loses track of array size.
For example this doesn't work:
int x[10][20];
void foo(int *ptr)
{
//the numbers 10 and 20 have not been passed through
}
But you can change it to
int x[10][20];
void foo(int arr[10][20])
{
//the numbers 10 and 20 are available
}
MatrixChainOrder is supposed to return a number, according to this link
int MatrixChainOrder(int s[100][100], int p[], int n)
{
int m[100][100];
for (int i = 0; i < 100; i++) m[i][i] = 0;
for (int i = 0; i < 100; i++) s[i][i] = 0;
int q = 0;
for (int L = 2; L <= n; L++) {
for (int i = 1; i <= n - L + 1; i++) {
int j = i + L - 1;
m[i][j] = INT_MAX;
for (int k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return q;
}
int main()
{
int arr[] = { 40, 20, 30, 10, 30 };
int array_size = sizeof(arr) / sizeof(int);
int n = array_size - 1;
int s[100][100];
int minimum = MatrixChainOrder(s, arr, n);
printf("{ 40, 20, 30, 10, 30 } should result in 26000 : %d\n", minimum);
return 0;
}
Likewise you can change your Print function
void Print(int s[100][100], int i, int j)
{
if (i < 0 || i >= 100 || j < 0 || j >= 100)
{
cout << "array bound error\n";
}
//safely access s[i][j] ...
}

C++: Sorting strings using LSD radix sort crashing

I have written some code that is meant to sort an array of strings using the radix sort, starting with the least significant digit. This function assumes all of the strings are the same length and each character is lowercase.
I am encountering crashes whenever I get to the loop in which I assign values to the temporary array. You can see my function here:
#ifndef RADIX_H
#define RADIX_H
#include <string>
#include <iostream>
using namespace std;
void lsd_string_radix(string array[], int array_size, int max_chars)
{
string *temp = new string[array_size];
for(int i = max_chars - 1; i >= 0; i--)
{
int count[26] = {0};
for(int j = 0; j < array_size; j++)
{
count[static_cast<int>(array[j][i]) - 97]++;
}
for(int j = 1; j <= 26; j++)
{
count[j] += count[j - 1];
}
for(int j = 0; j < array_size; j++)
{
temp[count[static_cast<int>(array[j][i])]++] = array[j]; // crashes here
}
for(int j = 0; j < array_size; j++)
{
array[j] = temp[j];
}
}
}
#endif
I'm guessing I have a failing in logic but I can't figure it out for the life of me.
After the second loop, count[0] should be zero, and the third loop is missing a -97. This example fixes the problem using count of size 27 instead of 26. The first loop in this example uses -96, so count[0] = 0, count[1] = # instances of 'a's, count[2] = # instances of 'b's, ... . count[26] = # instances of 'z's but it's only used in the first loop. It's not needed, but it's simpler to put a count of 'z's there rather than adding an if statement to avoid storing a count at count[26].
#include<iomanip>
#include<iostream>
#include <string>
using namespace std;
void lsd_string_radix(string array[], int array_size, int max_chars)
{
string *temp = new string[array_size];
for(int i = max_chars - 1; i >= 0; i--)
{
int count[27] = {0};
for(int j = 0; j < array_size; j++)
count[static_cast<int>(array[j][i]) - 96]++;
for(int j = 2; j < 26; j++)
count[j] += count[j - 1];
for(int j = 0; j < array_size; j++)
temp[count[static_cast<int>(array[j][i]) - 97]++] = array[j];
for(int j = 0; j < array_size; j++)
array[j] = temp[j];
}
}
int main()
{
string a[6] = {"mnop", "ijkl", "efgh", "uvwx", "qrst", "abcd"};
lsd_string_radix(a, 6, 4);
for(size_t i = 0; i < 6; i++)
cout << a[i] << endl;
return 0;
}
If the size of count[] is to be 26, the first loop needs to be modified:
for(int j = 0; j < array_size; j++){
if(array[j][i] == 'z')continue;
count[static_cast<int>(array[j][i]) - 96]++;
}
or the first two loops are modified:
for(int j = 0; j < array_size; j++)
count[static_cast<int>(array[j][i]) - 97]++;
int m = 0;
int n;
for(int j = 0; j < 26; j++){
n = count[j];
count[j] = m;
m += n;
}

getting WA when I try to submit mkbudget spoj

I cannot understand/think of a case where my code fails to give correct output.
Link to the problem: http://www.spoj.pl/problems/MKBUDGET/
The problem clearly has a DP solution. I am posting my solution below:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<vector <int> > opt;
void compute_opt(vector<int> A,int n,int hire,int fire,int sal,int max_a)
{
for(int i = A[0]; i <= max_a; i++) //for num workers in 1st month
opt[0][i] = i*(hire + sal);
for(int i = 1; i < n; i++) //num of months
for(int j = A[i]; j <= max_a; j++) //num of workers for ith month >=A[i] and <= max_a
{
opt[i][j] = opt[i-1][A[i-1]] + j*sal + (A[i] > A[i-1] ? (A[i]-A[i-1])*hire : (A[i-1] - A[i])*fire);
for(int k = A[i-1]; k <= max_a; k++)
opt[i][j] = min(opt[i][j], opt[i-1][k] + j*sal + (j>k ? (j-k)*hire : (k-j)*fire));
}
}
int ans(vector<int> A, int n, int max_a)
{
int ret = opt[n-1][A[n-1]];
for(int i = A[n-1]; i <= max_a; i++)
ret = min (ret, opt[n-1][i]);
return ret;
}
int main()
{
vector<int> A;
int n, hire, fire, sal,max_a, c = 1;
while(1)
{
cin >> n;
if(n == 0)
break;
A.clear();
opt.clear();
max_a = 0;
cin >> hire >> sal >> fire;
A.resize(n);
for(int i = 0; i < n; i++)
{cin >> A[i];
max_a = max(max_a,A[i]);
}
opt.resize(n);
for(int i = 0; i < n; i++)
opt[i].resize(max_a + 2);
compute_opt(A,n,hire,fire,sal,max_a);
cout << "Case " << c << ", cost = $" << ans(A,n,max_a) << endl;
c++;
}
return 0;
}
I am getting correct answers for the two sample test cases but I get a WA when I submit. Any help ?
OK, so your problem is that you disallow the case where you hire any number of employees between A[i] and A[i - 1]. Maybe it's a good idea to fire some unneeded employees, but not all. That's why you get WA. I modified your code and got it accepted:
void compute_opt(vector<int> A,int n,int hire,int fire,int sal,int max_a)
{
// Fill all disallowed entries with infinity
for (int i = 0; i < A[0]; ++i)
opt[0][i] = 1000000000;
for(int i = A[0]; i <= max_a; i++) //for num workers in 1st month
opt[0][i] = i*(hire + sal);
for(int i = 1; i < n; i++)
for(int j = 0; j <= max_a; j++)
{
// No need for special case handling,
//just check all previous numbers of employees
opt[i][j] = 1000000000;
if (A[i] > j) continue;
for(int k = 0; k <= max_a; k++)
opt[i][j] = min(opt[i][j],
opt[i-1][k] + j*sal + (j>k ? (j-k)*hire : (k-j)*fire));
}
}
By the way, there's a "greedier" solution than the one you have that does not depend on the number of employees being small (so that the table can be allocated).