C++ - my for loop is not starting - c++

I wrote this code for java first. It should print the 2D array as a spiral. I wanted to try it in c++.. in java; there was a draw method. But c++ is not accepting array as a return type (can done by pointers) so I deleted the draw method and copied inside the main method. I commented the draw method where starts and ends. But now; the for loop which is after the draw method (i commented it too) is not starting. What's the problem; I cannot see it... Thanx for help.
int T ;
scanf("%d", &T);
int num[T];
for(int i = 0; i < T; i++){
scanf("%d", &num[i]);
}
for(int m = 0; m < T; m++){
int n = num[m];
int a[n][n];
//draw -start
int all = n*n;
int x = 0, y=0;
for(int counter=1; counter<=all; counter++){
for(int i = 0; i < n; i++){
a[x][y] = counter++;
y++;}
x++; y--;
for(int i = 0; i < n-1; i++){
a[x][y] = counter++;
x++;}
x--; y--;
for(int i = 0; i < n-1; i++){
a[x][y] = counter++;}
x--; y++;
for(int i = 0; i < n-2; i++){
a[x][y] = counter++;}
y++; x++; n = n-2;}
//draw - end
//this for is not starting
for(int i = 0; i<n; i++){
printf("a");
for(int j = 0; i<n; j++){
printf("a");
printf("%d ", a[i][j]);
}
printf("\n");
}

You decrement n in the biggest cycle.
n = n-2;
This is why n < 0 when you reach the for you speak of and it is not looping.
I am almost certain you did not meant to modify n in this loop.

I neatened up your code and provided my answer in the comments.
int T ;
scanf("%d", &T);
int num[T];
for(int i = 0; i < T; i++){
scanf("%d", &num[i]);
}
for(int m = 0; m < T; m++){
int n = num[m];
int a[n][n];
//draw -start
int all = n*n;
int x = 0, y=0;
for(counter=1; counter<=all; counter++){
for(int i = 0; i < n; i++) {
a[x][y] = counter++;
y++;
}
x++;
y--;
for(int i = 0; i < n-1; i++) {
a[x][y] = counter++;
x++;
}
x--;
y--;
for(int i = 0; i < n-1; i++) {
a[x][y] = counter++;
}
x--;
y++;
for(int i = 0; i < n-2; i++) {
a[x][y] = counter++;
}
y++;
x++;
n = n-2; //n = n - 2; all = n * n times?
}
for(int i = 0; i<n; i++){
printf("a");
for(int j = 0; i<n; j++){
printf("a");
printf("%d ", a[i][j]);
}
printf("\n");
}
}
in particular look at this line
n = n-2; //n = n - 2; all = n * n times?

Related

C++ Gauss–Seidel method

this is a piece of code for a simple iteration method for solving systems of linear algebraic equations:
double* iter(double** a, double* y, int n, int& iter)
{
double* res = new double[n];
int i, j;
for (i = 0; i < n; i++)
{
res[i] = y[i] / a[i][i];
}
double eps = 0.0001;
double* Xn = new double[n];
do {
iter++;
for (i = 0; i < n; i++) {
Xn[i] = y[i] / a[i][i];
for (j = 0; j < n; j++) {
if (i == j)
continue;
else {
Xn[i] -= a[i][j] / a[i][i] * res[j];
}
}
}
bool flag = true;
for (i = 0; i < n - 1; i++) {
if (fabs(Xn[i] - res[i]) > eps) {
flag = false;
break;
}
}
for (i = 0; i < n; i++) {
res[i] = Xn[i];
}
if (flag)
break;
} while (1);
return res;
}
and formula for it:
but I would like to implement the seidel method.and slightly changed the code according to the formula below
for (i = 0; i < n; i++) {
Xn[i] = y[i] / a[i][i];
for (j = 0; j < i-1; j++) {
Xn[i] -= a[i][j] / a[i][i] * Xn[j];
}
for (j = i+1; j < n; j++){
Xn[i] -= a[i][j] / a[i][i] * res[j];
}
}
but I'm not getting exactly what I expected:
I would be grateful if you could tell me where I made a mistake. thank you in advance for your answers.
Your mistake lies in the new implementation.
The first sum of the Seidel method sums up to the element before the diagonal, while your for loop goes up to two elements before the diagonal.
Instead of
for(j = 0; j < i-1; j++)
you should have
for(j = 0; j < i; j++)
Note that Gauss Seidel method is applicable if the elements on the diagonal are non-zero.

Fill two dimensional array with spiral

The task is to fill two dimens array [N][M] in a spiral with numbers starting with 1.
My code doesn't work when one of the elements (N or M) is odd or both are odd.
When I use two different even or two same even numbers it works.
I need help to do it so it would work in any case, with any N and M.
p.s. please keep my code (don't make dynamic array, keep defines and etc.)
https://pastebin.com/9HufHYBg
#include <iostream>
#define N 6
#define M 4
int nums = 1;
int p = 1;
int arr[N][M];
using namespace std;
void printArr(){
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j++){
cout << arr[i][j] << "\t";
}
cout << endl;
}
}
void circle (int k){
// levo pravo
for (int i = 0+k; i < M-k; i++){
arr[N-N+k][i] = nums;
nums++;
}
// verh niz
nums--;
for (int i = 0+k; i < N-k; i++){
arr[i][M-1-k] = nums;
nums++;
}
// pravo levo
nums--;
for (int i = M-p; i >= 0+k; i--){
arr[N-1-k][i] = nums;
nums++;
}
// niz verh
nums--;
for (int i = N-p; i > 0+k; i--){
arr[i][0+k] = nums;
nums++;
}
p++;
}
int main(){
if (M<N){
for (int k = 0; k < M/2; k++){
circle(k);
}
} else {
for (int k = 0; k < N/2; k++){
circle(k);
}
}
printArr();
return 0;
}
To summarise, I managed to solve using two changes:
first, we change the limits of the main call so that we reach the centre everytime, and second, we avoid overwriting of already populated indices. Here, I stop this overwriting by checking by using an if statement before every assignment. But, cleaner solutions might be possible for the same.
Tested for various combinations (odd-odd, even-even, odd-even, odd-odd-not-same, odd-odd-same etc..)
#include <iostream>
#define N 9
#define M 7
int nums = 1;
int p = 1;
int arr[N][M];
using namespace std;
void printArr(){
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j++){
cout << arr[i][j] << "\t";
}
cout << endl;
}
}
void circle (int k){
// levo pravo
for (int i = 0+k; i < M-k; i++){
if (arr[N-N+k][i] == 0)
arr[N-N+k][i] = nums;
nums++;
}
// verh niz
nums--;
for (int i = 0+k; i < N-k; i++){
if (arr[i][M-1-k] == 0)
arr[i][M-1-k] = nums;
nums++;
}
// pravo levo
nums--;
for (int i = M-p; i >= 0+k; i--){
if (arr[N-1-k][i]==0)
arr[N-1-k][i] = nums;
nums++;
}
// niz verh
nums--;
for (int i = N-p; i > 0+k; i--){
if (arr[i][0+k] == 0)
arr[i][0+k] = nums;
nums++;
}
p++;
}
int main(){
if (M<N){
for (int k = 0; k < (M+1)/2; k++){
circle(k);
}
} else {
for (int k = 0; k < (N+1)/2; k++){
circle(k);
}
}
printArr();
return 0;
}
For odd N or M you should print a line after the last iteration. You can't print a circle because the surface to print doesn't have 2 or more lines. One way to do it is checking if N or M are odd and, then, print a line to fill the spiral: https://godbolt.org/z/6oavKGPqf
I've added vert_line function and hor_line to your code to print that final line (vertical or horizontal).
void hor_line(int k){
for (int i = 0+k; i < M-k; i++){
arr[N-N+k][i] = nums;
nums++;
}
}
void vert_line(int k){
for (int i = 0+k; i < N-k; i++){
arr[i][M-1-k] = nums;
nums++;
}
}
int main(){
if (M<N){
int k{0};
for (; k < M/2; k++){
circle(k);
}
if (M % 2 != 0){
vert_line(k);
}
} else {
int k{0};
for (; k < N/2; k++){
circle(k);
}
if (N % 2 != 0){
hor_line(k);
}
}
printArr();
return 0;
}

How do I find errors in a recursive function?

I'm trying to find the smallest of the biggest sum of each column of every possible permutations of a given 2D array NxN, where the values in each row can shift towards the left. For example, the array
4 6
3 7
would have 4 possibles permutations:
4 6 6 4 4 6 6 4
3 7 3 7 7 3 7 3
The biggest sum of each permutation is respectively, 13, 11, 11, 13. Thus the smallest of the biggest sums is 11. I have written a recursive function that should work, but for some reason, it only works for arrays that are smaller than 6x6... I'm new at programming, and just recently learned about recursion, any help or counsel on how to think recursively and to debug code would be greatly appreciated...
For the array 4x4
7410 1371 2665 3195
4775 4130 6499 3414
300 2092 4009 7638
5351 210 7225 7207
The answer is 18349, and my code gives me the correct answer.
However, for the array 6x6
5219 842 7793 2098 5109 2621
1372 3253 3804 5652 810 1620
4894 6792 1784 4335 4772 6656
3203 1070 4716 5335 1157 6855
5529 2767 2205 408 7516 7454
375 7036 2597 5288 937 2893
The answer should be 23733, but I've got 24176. How is this possible?
Here's my code:
#include <iostream>
using namespace std;
#define MAX_N 1000
int n, matrix[MAX_N][MAX_N], shift[MAX_N] = {0}, minSum = 100000000;
void possibTree(int position){
//Base case
if(position == n){
for (int i = 0; i < n; i++) {
// Temporary array to store the values in the row that just shifted towards the left
int temp[MAX_N] = {0};
for (int j = 0; j < n; j++) {
if(j - shift[i] < 0)
temp[n+(j-shift[i])] = matrix[i][j];
else
temp[j-shift[i]] = matrix[i][j];
}
for (int k = 0; k < n; k++)
matrix[i][k] = temp[k];
}
int max = 0;
for (int i = 0; i < n; i++) {
int temp = 0;
for (int j = 0; j < n; j++) {
temp += matrix[j][i];
}
if(temp > max)
max = temp;
}
if(minSum > max)
minSum = max;
return;
}
for (int i = 0; i < n; i++) {
shift[position] = i;
possibTree(position+1);
}
return;
}
int main() {
while(cin >> n){
memset(matrix, 0, sizeof(matrix));
memset(shift, 0, sizeof(shift));
if(n == -1) // The user enters "-1" to end the loop and terminate the program.
return 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
possibTree(0);
cout << minSum << endl;
minSum = 100000000;
}
return 0;
}
Ok I believe I understand my mistake, I have to reset the matrix to its original state at the end of each base case, when the matrices are small, the code is still capable of finding all the possible biggest sums, but when the matrices got bigger, some of the possibilities weren't generated. Here's my code:
#include <iostream>
using namespace std;
#define MAX_N 1000
int n, matrix[MAX_N][MAX_N], OrigMatrix[MAX_N][MAX_N], shift[MAX_N] = {0}, minSum = 100000000;
void possibTree(int position){
//Base case
if(position == n){
for (int i = 0; i < n; i++) {
// Temporary array to store the values in the row that just shifted towards the left
int temp[MAX_N] = {0};
for (int j = 0; j < n; j++) {
if(j - shift[i] < 0)
temp[n+(j-shift[i])] = matrix[i][j];
else
temp[j-shift[i]] = matrix[i][j];
}
for (int k = 0; k < n; k++)
matrix[i][k] = temp[k];
}
int max = 0;
for (int i = 0; i < n; i++) {
int temp = 0;
for (int j = 0; j < n; j++) {
temp += matrix[j][i];
}
if(temp > max)
max = temp;
}
if(minSum > max)
minSum = max;
//EDITS
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = OrigMatrix[i][j];
}
}
return;
}
for (int i = 0; i < n; i++) {
shift[position] = i;
possibTree(position+1);
}
return;
}
int main() {
while(cin >> n){
memset(matrix, 0, sizeof(matrix));
memset(shift, 0, sizeof(shift));
if(n == -1) // The user enters "-1" to end the loop and terminate the program.
return 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> matrix[i][j];
}
}
//EDITS
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
OrigMatrix[i][j] = matrix[i][j];
}
}
possibTree(0);
cout << minSum << endl;
minSum = 100000000;
}
return 0;
}

How to correctly divide square matrix?

const int n = 4, m = 4;
int i, j, k, sum;
srand(time(NULL));
int mat[n][m];
printf("Matrix( %d, %d): \n",n,m);
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
mat[i][j] = rand()%100-50;
printf("%4d", mat[i][j]);
}
cout<<endl;
}
for(i = 0; i < n/2; i++)
{
for(j = 0; j < m/2; j++)
{
mat[i][j] = 0;
}
}
How to divide square matrix on 4 equal square blocks? My code divide only 1st part. I think I need to use n/2 < n, but how to do it in cycle?
First block:
for (int i=0; i<n/2; i++) {
for(int j=0; j<m/2; j++) {
// your code
}
}
Second block:
for (int i=0; i<n/2; i++) {
for(int j=m/2; j<m; j++) {
// your code
}
}
Third block:
for (int i=n/2; i<n; i++) {
for(int j=0; j<m/2; j++) {
// your code
}
}
Forth block:
for (int i=n/2; i<n; i++) {
for(int j=m/2; j<m; j++) {
// your code
}
}
Here is a more compact code that can fetch your matrix blocks by rows sequentially:
for (int p = 0; p <= 1, p++)
{
for (int q = 0; q <= 1, q++)
{
for(i = p*n/2; i < (p+1)*n/2; i++)
{
for (j = q*m/2; j < (q+1)*m/2; j++)
{
mat[i][j] = 0;
}
}
}
}

Infinite Impluse Response (IIR) Function

I am trying to design a signal class which includes an IIR filter function. The following is my code:
void signal::IIRFilter(vector<double> coefA, vector<double> coefB){
double ** temp;
temp = new double*[_nchannels];
for(int i = 0; i < _nchannels; i++){
temp[i] = new double[_ninstances];
}
for(int i = 0; i < _nchannels; i++){
for(int j = 0; j < _ninstances; j++){
temp[i][j] = 0;
}
}
for(int i = 0; i < _nchannels; i++){
for (int j = 0; j < _ninstances; j++){
int sum1 = 0;
int sum2 = 0;
for(int k = 0; k < coefA.size(); k++){
if ((j-k) > 0 ){
sum1 += coefA.at(k)*temp[i][j-k-1];
}
}
for (int m = 0; m < coefB.size(); m++){
if(j >= m){
sum2 += coefB.at(m)*_data[i][j-m];
}
}
temp[i][j] = sum2-sum1;
}
}
for(int i = 0; i < _nchannels; i++){
for(int j = 0; j < _ninstances; j++){
_data[i][j] = temp[i][j];
}
}
}
_data contains my original signal, _ninstances is my number of samples, and _nchannels is the number of channels. The function compiles and works but the result I am getting is different from the result given by MATLAB. I even use the same coefficients given by MATLAB. Is there anything that I'm doing wrong in my function?
One issue that I can see is that you are declaring sum1 and sum2 as integers when they should be double. To avoid this kind of error in the future, you should try configuring your compiler to warn of implicit conversions. In g++, this is accomplished using the -Wconversion flag.