When I use an array, the following code works well. I tried to replace array with std::vector, but found that procedures often appear abnormalities, need to run more times. Anything I missed? I am using g++ 10.3.
#include <iostream>
#include <vector>
int main() {
int n = 3;
for (int k = 1; k <= 4; ++k) {
// int *A = new int[k]();
std::vector<int> A(k, 0);
int i = 0;
for (; i >= 0; A[i]++) {
for (int j = 0; j < k; ++j) {
std::cout << A[j] << " ";
}
std::cout << "\n";
for (i = k - 1; i >= 0 && A[i] == n - 1; i--)
A[i] = 0;
}
}
return 0;
}
In this for loop in its third part
for (; i >= 0; A[i]++) {
^^^^^^
the variable i can be equal to -1 after the inner loop
for (i = k - 1; i >= 0 && A[i] == n - 1; i--)
where the same variable i is used (for example when k is equal to 1).
So it is unimportant whether you are using a vector or an array. The program has undefined behavior.
Related
I am trying to write a program which checks if 3 (or more) elements of an array are the same.
I have written a code which works almost perfectly, but it gets stuck when there are 3 pairs of equal elements and I'm not sure how to fix it.
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n, a[10],skirt=0;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
if(a[i] == a[j])
{
skirt++;
}
}
}
cout<<skirt<<endl;
if(skirt>=3)
{
cout << "TAIP" << endl;
}
else
{
cout << "NE" << endl;
}
}
When I input
6
3 3 2 2 1 1 i
get "TAIP" but I need to get "NE".
You can use the following algorithm: first sort the array. Then iterate each adjacent pair. If they are equal, then increment counter, if not then reset counter to 1. If counter is 3, return true. If loop does not return true, then return false.
Add the following condition in the outer for loop
for(int i = 0; i < n - 2 && skirt != 3; i++)
^^^^^^^^^^^^^^^^^^^^^^^
{
skirt = 1;
^^^^^^^^^
for(int j = i + 1; j < n; j++)
{
if(a[i] == a[j])
{
skirt++;
}
}
}
Of course before the loop you should check whether n is not less than 3. For example
if ( not ( n < 3 ) )
{
for(int i = 0; i < n - 2 && skirt != 3; i++)
{
skirt = 1;
for(int j = i + 1; j < n; j++)
{
if(a[i] == a[j])
{
skirt++;
}
}
}
}
Here is a demonstrative program
#include <iostream>
using namespace std;
int main()
{
int a[] = { 6, 3, 3, 2, 2, 1, 1 };
int n = 7;
int skirt = 0;
if ( not ( n < 3 ) )
{
for(int i = 0; i < n - 2 && skirt != 3; i++)
{
skirt = 1;
for(int j = i + 1; j < n; j++)
{
if ( a[i] == a[j] )
{
skirt++;
}
}
}
}
cout << skirt << endl;
if ( skirt == 3 )
{
cout << "TAIP" << endl;
}
else
{
cout << "NE" << endl;
}
return 0;
}
Its output is
1
NE
because the array does not have 3 equal elements.
Reset skirt to 0 every time you increase i if it is less than 3, or break out the loop otherwise.
Another way to do this is using a std::map, which keeps a count of the number of times a given value occurs in your array. You would stop looking as soon as you have a number that has three occurrences.
Here's a 'minimalist' code version:
#include <iostream>
#include <map>
using std::cin; // Many folks (especially here on SO) don't like using the all-embracing
using std::cout; // ... statement, "using namespace std;". So, these 3 lines only 'use'
using std::endl; // ... what you actually need to!
int main() {
int n, a[10], skirt = 0;
std::map<int, int> gots;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n && skirt < 3; i++) {
skirt = 1;
if (gots.find(a[i]) != gots.end()) skirt = gots[a[i]] + 1;
gots.insert_or_assign(a[i], skirt);
}
cout << (skirt >= 3 ? "TAIP" : "NE") << endl;
return 0;
}
I'm not saying this is any better (or worse) than the other answers - just another way of approaching the problem, and making use of what the Standard Library has to offer. Also, with this approach, you could easily modify the code to count how many numbers occur three or more times, or any number of time.
Feel free to ask for further clarification and/or explanation.
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
I am currently working on this code. But there are some problems. First of all, if I run this code, it says array size in new-expression must be constant. If I make the array arr[n], this error message does not appear. Also this code makes error message when it gets to the line cout << arr[i][j] << endl; saying that invalid types 'int[int]' for array subscript. I do not understand why this error message comes out because I made the array arr[n][n] not arr[n].
What I want to make with this code is showing the magic-square for n*n if I type in n in the argument line.
This is my main.cc
#include <iostream>
#include <cstdlib>
#include <cstring>
#include "magic_square.h"
using namespace std;
int main(int argc, const char** argv) {
int n = atoi(argv[1]);
int *arr = new int[n][n];
if (n % 2 == 0 || n < 3)
return 0;
else
magicSquare(n, arr);
for (int i = 0, j = 0; i < n, j < n; i++, j++)
cout << arr[i][j] << endl;
delete[] arr;
return 0;
}
This is my magic_square.cc. I did not add magic_square.h as it is only the declaration of the funtion void magicSquare(int n, int* arr).
#include <iostream>
#include "magic_square.h"
void magicSquare(int n, int* arr) {
for (int i = 0, j = n/2, num = 1; num <= n*n; num++) {
arr[i][j] = num;
if (num % n == 0) {
i++;
}
else {
i--, j++;
if (i < 0)
i = n - 1;
if (j > (n - 1))
j = 0;
}
}
}
~
Can anybody help me with this errors? Thanks in advance!
Take account that the for condition is just working because the two comma separated expressions are true at the same time.
for (int i = 0, j = 0; i < n, j < n; i++, j++)
That end condition is equivalent to only do the last test, since its result will be the result of the comma separated expression.
Probably you should have written this:
for (int i = 0, j = 0; i < n && j < n; i++, j++)
This code that runs only for odd N. The problem is that there are no ideas how to add support for even values N
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
setlocale(0, "");
int n;
cout << "Enter the size of the magic square - ";
cin >> n;
int **matrix = new int *[n];
for (int i = 0; i < n; ++i)
{
matrix[i] = new int[n];
}
int nsqr = n * n;
int i = 0, j = n / 2;
for (int k = 1; k <= nsqr; ++k)
{
matrix[i][j] = k;
i--;
j++;
if (k % n == 0)
{
i += 2;
--j;
}
else
{
if (j == n)
{
j -= n;
}
else if (i < 0)
{
i += n;
}
}
}
cout << "\n\nMagic square size - " << n << "\n\n";
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << matrix[i][j] << "\t";
}
cout << endl;
}
for (i = 0; i < n; i++)
delete[] matrix[i];
delete[] matrix;
system("pause >> null");
return 0;
}
I would be grateful for tips on troubleshooting.
If i'm not mistaken, the problem is in this line:
int i = 0, j = n / 2;
But i don't know how to change the code to support even values
I would assume that you meant normal magic square (where the number are restricted to 1,2..n^2)
First of all, it's impposible to construct such magic square for n=2.
2nd, you would need an whole new algorithm for it, which is much more complicated. The problem (constructing magic square for any even number) is solved in this paper and while there isn't any psaudo code there, the implementation from the explenation is quite straightforward (long one though).
the problem is here:
i = 0;
int j = n / 2;
for (int k = 1; k <= nsqr; ++k)
{
matrix[i][j] = k;
i--;
}
look how you decrement i inside the loop and making it as an index of the array so:
matrix[-3][j] = k; // will be in your code
you are messing deliberately with the indexes of the array
I found answer on my question in this artcile
I made full revision my algorithm based on this article. Later posted listing the resulting program
This code should produce a solved sudoku matrix, however the while statement puts it in an infinite loop. Removing the while statement gives me a matrix with some values still 99 or 0. And i can't generate 9 random numbers uniquely one by one.
IF YOU WANT TO RUN AND CHECK THE CODE, REMOVE THE WHILE STATEMENT.
int a[9][9];
int b[9][9];
int inputvalue(int x, int y, int value) //checks horizontally, vertically and 3*3matrix for conflicts
{
int i, j;
for (i = 0; i < 9; i++)
{
if (value == a[x][i] || value == a[i][y])
return 0;
}
for (i = (x / 3) * 3; i <= ((x / 3) * 3) + 2; i++)
{
for (j = (y / 3) * 3; j <= ((y / 3) * 3) + 2; j++)
if (b[i][j] == value)
return 0;
}
return value;
}
int main()
{
int i, j, k;
unsigned int s;
cout << "sudoku\n";
time_t t;
s = (unsigned) time(&t);
srand(s);
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
a[i][j] = 99;
}
for (i = 0; i < 9; i++)
{
for (j = 1; j <= 9; j++)//j is basically the value being given to cells in the matrix while k assigns the column no.
while(a[i][k]==99||a[i][k]==0)
{
k = rand() % 9;
a[i][k] = inputvalue(i, k, j);
}
}
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
getch();
}
You are using assignment =, instead of equality == here:
while(a[i][k]=99||a[i][k]=0)
^ ^
this should be:
while(a[i][k]==99||a[i][k]==0)
a[i][k]=99 will always evaluate to true since 99 is non-zero, although your original code does not compile for me under gcc as it is, so I suspect the code you are running either has some parenthesizes or is slightly different.
Also using k in the while loop before it is initialized is undefined behavior and it is unclear that your termination logic makes sense for a k that is constantly changing for each loop iteration.
Another source of the infinite loop is inputvalue which seems to get stuck returning 0 in some instances, so you need to tweak that a bit to prevent infinite loops.
Also, srand(time(NULL)); is a more common way to initialize the pseudo-random number generator