edit a range of elements inside a 2d array? - c++

well ive been trying to edit the element of an array so lets assume that we have a 2d array
so
a 2d array 9 x 9;
for(... ... ... ++)
{
for(.. ... ...++){}
}
lets say that the code will use another set of for loops to display the 2d array its a simple array nothing fancy
00000000
00000000
00000000...
so if i wanted to to display an E from elements[1][0] to [2][3] how would i do that?
00000000
eeeeeeee
eeee0000
00000000
what i had in mind was something like while(x < y)
{ array[x++][y];}
but this idea doesnt seem to work.
would gladly take any help. thx
for(int i=0; i<9; i++) //This loops on the rows.
{
for(int j=0; j<9; j++) //This loops on the columns
{
board[i][j] = grid; // set the array to the char on grid '0'.
}
}
board[s_col][s_row] = 'Z';
while(s_col < e_col)//s_col is the start of the rows and columns
//{
//if(s_col != e_col)
{
++s_col;
board[s_col][s_row];
}
//}
//cout << board[s_col][s_row++] <<endl;
// display the array
for(int i=0; i<9; i++) //This loops on the rows.
{
for(int j=0; j<9; j++) //This loops on the columns
{
cout << board[i][j] << " ";
}
cout << endl;
}

You were on the right track with the approach:
for(... ... ... ++)
{
for(.. ... ...++){}
}
Here is some code that should help you:
#include <stdio.h>
#include <memory.h>
#define MAX_ROW 4
#define MAX_COL 8
void fillRange(char fillChar, int startRow, int startCol, int count);
char myArray[MAX_ROW][MAX_COL];
void printArray();
int main(int argc, char *argv[])
{
memset(myArray, '0', sizeof(myArray));
printf("\nBefore:\n");
printArray();
fillRange('e', 1, 0, 12);
printf("\nAfter:\n");
printArray();
}
void fillRange(char fillChar, int startRow, int startCol, int count)
{
int i, j, filledChars = 0;
for(i = startRow; i < MAX_ROW; i++)
{
for(j = startCol; j < MAX_COL; j++)
{
myArray[i][j] = fillChar;
if(++filledChars == count)
return;
}
}
}
void printArray()
{
int i, j;
for(i = 0; i < MAX_ROW; i++)
{
for(j = 0; j < MAX_COL; j++)
putchar(myArray[i][j]);
printf("\n");
}
}
If you instead wanted to end at a particular point in the array then you just need to change the condition that triggers the return.

This is one of the many reasons why the more coding you do the more you tend to avoid 2D arrays of the sort you have.
Instead you use a 1D array like this: board[i][j] == board_1D[i*num_columns+j]. That also means you can just iterate through the entire board in a single for loop.
Now you simply calculate the begin and end indices of your e range, and simply test if your counter is within that range. In other words, you have a single if statement inside your inner-most loop.
You can, of course, convert your i,j 2D indices into the equivalent 1D index and take the same approach. index_1D = i*9+j;
I'll leave the code to you.

Dealing with a sequence of adjacent values is easiest done when you have an underlying contiguous array and you don't need to deal with double indexing (see Adam's answer on that). However, in your simple case it also quite doable:
You'd initialize your row and column variables with the start row and column (in your case 0 and 1). You then walk with your column until you reached either the target column (2) and you are on the target row (3) or you reached the end of the matrix in which case you set the column to 0 and increment the row.

Related

C++ Merge Sort Visualizer

I am trying to make a c++ console application that tries to show you how merge sort looks like. I understand merge sort, and I created a program that organizes a vector of strings called sort_visualize, and each string in it is filled with many #. This is completely randomized for every string. The merge sort will organize them depending on length, instead of the traditional number organizing people do with it. Every time I make a change to the vector, I also clear the screen and print out the entire vector through a draw function, to give the effect of it actively visualizing the sort every frame. The problem is that when I use the draw function to print out the entire sort_visualize string, it does not print out any changes that I have made to it, and prints out the same thing over and over again until the end, when it finally prints the sorted order. What is going on? I Don't understand. I even tried changing the draw(sort_visualize) to draw(sort_visualize_), and that shows small areas of the vector it is working on. Makes no sense. Please try this code and tell me any solutions. Thank you.
Here's the code:
#include <vector>
#include <iostream>
#include <ctime>
#include "stdlib.h"
#include "windows.h"
using namespace std;
void merge_sort(vector<string> &sort_visual_);
void merge_halves(vector<string>&left, vector<string>& right, vector<string>& sort_visual_);
void draw(vector <string> &sort_visual_);
vector <string> sort_visual;
int main()
{
srand(time(NULL));
//vector
vector<int> num_list;
//fill vector with random integers
for (int i = 0; i < 40; i++)
num_list.push_back(rand() % 40);
//Fill the visualizer strings which will be bars with #'s
for (int i = 0; i < num_list.size(); i++)
{
sort_visual.push_back("");
string temp;
for (int j = 0; j < num_list.at(i); j++)
{
temp.push_back('#');
}
sort_visual.at(i) = temp;
}
draw(sort_visual);
system("pause");
//sort function
merge_sort(sort_visual);
}
void merge_sort(vector<string> &sort_visual_)
{
//dont do anything if the size of vector is 0 or 1.
if (sort_visual_.size() <= 1) return;
//middle of vector is size/2
int mid = sort_visual_.size() / 2;
//2 vectors created for left half and right half
vector<string> left;
vector<string> right;
//divided vectors
for (int j = 0; j < mid; j++)
{
left.push_back(sort_visual_[j]); //add all the elements from left side of original vector into the left vector
}
for (int j = 0; j < (sort_visual_.size()) - mid; j++)
{
right.push_back(sort_visual_[mid + j]);//add all the elements from right side of original vector into the right vector
}
//recursive function for dividing the left and right vectors until they are length of 1
merge_sort(left);
merge_sort(right);
//do the actual merging function
merge_halves(left, right, sort_visual_);
}
void merge_halves(vector<string>&left, vector<string>&right, vector<string>& sort_visual_) //pass in 3 vectors
{
// sizes of each vector (left and right)
int nL = left.size();
int nR = right.size();
//declaring variables pointint to elements for each vector. i will represent finished produce vector
int i = 0, j = 0, k = 0;
//as long as j and k are less than the left and right sizes
while (j < nL && k < nR)
{
if (left[j].length() < right[k].length()) //if the string in the left vector is smaller than string in right vector
{
sort_visual_[i] = left[j];//ad the string from left vector in the sort_visuals vector(which is the final product)
j++;//increment j to move on
}
else
{
sort_visual_[i] = right[k];//otherwise add the string from right vector in the sort_visual vector
k++; //increment k to move on
}
i++; //i is the final vector, and we have to increment it to set it up to take in the next number
system("CLS");
draw(sort_visual);
Sleep(15);
}
while (j < nL)
{
sort_visual_[i] = left[j];
j++; i++;
system("CLS");
draw(sort_visual);
Sleep(15);
}
while (k < nR)
{
sort_visual_[i] = right[k];
k++; i++;
system("CLS");
draw(sort_visual);
Sleep(15);
}
}
void draw(vector <string> &sort_visual)
{
for (int i = 0; i < sort_visual.size(); i++)
{
cout << sort_visual.at(i) << endl;
}
}
In merge_halves you work on sort_visual_ but draw sort_visual which is a global that does not seem to be changed. Make sure there are no globals and it will be harder to make mistakes.

How to Compare multiple variables at the same time in the C++?

I'm making Sudoku validater program that checks whether solved sudoku is correct or not, In that program i need to compare multiple variables together to check whether they are equal or not...
I have provided a snippet of code, what i have tried, whether every su[][] has different value or not. I'm not getting expecting result...
I want to make sure that all the values in su[][] are unequal.
How can i achieve the same, what are mistakes in my snippet?
Thanks...
for(int i=0 ; i<9 ;++i){ //for checking a entire row
if(!(su[i][0]!=su[i][1]!=su[i][2]!=su[i][3]!=su[i][4]!=su[i][5]!=su[i][6]!=su[i][7]!=su[i][8])){
system("cls");
cout<<"SUDOKU'S SOLUTION IS INCORRECT!!";
exit(0);
}
}
To check for each column uniqueness like that you would have to compare each element to the other ones in a column.
e.g.:
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
for (int k = j + 1; k < 9; ++k) {
if (su[i][j] == su[i][k]) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
}
Since there are only 8 elements per row this cubic solution shouldn't give you much overhead.
If you had a higher number N of elements you could initialize an array of size N with 0 and transverse the column. For the i-th element in the column you add 1 to that elements position in the array. Then transverse the array. If there's a position whose value is different from 1, it means you have a duplicated value in the column.
e.g.:
for (int i = 0; i < N; ++i) {
int arr[N] = {0};
for (int j = 0; j < N; ++j)
++arr[su[i][j] - 1];
for (int i = 0; i < N; ++i) {
if (arr[i] != 1) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
This approach is way more faster than the first one for high values of N.
The codes above check the uniqueness for each column, you would still have to check for each row.
PS: I have not tested the codes, it may have a bug, but hope you get the idea.

C++ how to modify a 2D vector of objects size in a function initialized in the constructor?

Since I'm Italian, the function names are in Italian but really simple to understand: immagine=image, inserisci=insert, altezza=height, larghezza=width,mosaico =mosaic, righe=rows, colonne=columns.
So this program has 2 classes: an image with its attributes and a mosaic, which contains n images and this is represented through a 2D vector of obj Image (Immagine). The 2D vector has to be initialized in the constructor with r rows and c columns and using the inserisci (insert/add) function will then grow its dimension. Then if the element passed in the insert function has more rows/columns the insert function has to add the needed rows and columns in order to insert the element.
The problem is that even though I used pointers/references, every time I try to insert an element with a size that is bigger than the one initialized in the constructor, it gives me an error, meaning that the 2D vector that I modify in the insert function is not really edited... (look at the main when I insert: m2.inserisci(i4, 4, 4, &m2.immagini) since 4 rows > inital size of rows and same for columns gives me a runnning error..) Hope it is clear. This is my code:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
class Immagine{
private:
string nome;
public:
int altezza;
int larghezza;
Immagine(string,int,int);
string toString();
};
Immagine::Immagine(string n, int a, int l){
nome = n;
altezza = a;
larghezza= l;
}
string Immagine::toString(){
return nome;
}
class Mosaico{
public:
Mosaico(int, int,Immagine,vector< vector<Immagine> >*);
int getRighe();
int getColonne();
string getImmagine(int,int);
bool exist(int, int);
Immagine getIm(int,int);
void inserisci(Immagine,int,int,vector< vector<Immagine> >*);
vector< vector<Immagine> > immagini;
vector< vector<Immagine> >* aPointer= &immagini;
};
Mosaico::Mosaico(int r, int c,Immagine imm, vector< vector<Immagine> >* immag ){
(*immag).resize(r);
for(int i=0; i<(*immag).size(); i++)
for(int j=0; j<c; j++)
(*immag)[i].insert((*immag)[i].begin()+j,imm);
}
bool Mosaico::exist(int r, int c){
for(int i = 0; i < getRighe(); i++){
for(int j=0; j<getColonne(); j++){
if(i==r && j==c && immagini[r][c].toString()!= " "){
return true;
}
}
}
return false;
}
int Mosaico::getRighe(){
return immagini.size();
}
int Mosaico::getColonne(){
return immagini[1].size();
}
string Mosaico::getImmagine(int r, int c){
if(exist(r,c))
return immagini[r][c].toString();
}
Immagine Mosaico::getIm(int r, int c){
return immagini[r][c];
}
void Mosaico::inserisci(Immagine imm,int r, int c, vector< vector<Immagine> >* immag){
if(r<(*immag).size() && c<(*immag)[0].size()){
(*immag)[r][c]=imm;
}
else if(r>=(*immag).size() && c>=(*immag)[0].size()){
(*immag).resize(r);
for(int i=0; i<r; i++){
for(int j=(*immag)[0].size(); j<c; j++){
(*immag)[i].insert((*immag)[i].begin()+j, imm);
}
}
(*immag)[r][c]=imm;
}
else if(r>=(*immag).size() && c<(*immag)[0].size()){
(*immag).resize(r);
(*immag)[r][c]=imm;
}
else if(r<(*immag).size() && c>=(*immag)[0].size()){
for(int i=0; i<(*immag).size(); i++){
for(int j=(*immag)[0].size(); j<c; j++){
(*immag)[i].insert((*immag)[i].begin()+j, imm);
}
}
(*immag)[r][c]=imm;
}
}
int main() {
Immagine i1 ("I01",300,200);
Immagine i2 ("I02",300,400);
Immagine i3 ("I03",400,200);
Immagine i4 ("I04",400,400);
cout << "Creo un mosaico 2x2 con quattro immagini" <<endl;
Mosaico m2(2,2,i1,&m2.immagini) ;
cout<<m2.getRighe()<<endl;
cout<<m2.getColonne()<<endl;
for (int i=0; i < m2.getRighe(); i++) {
for (int j=0; j < m2.getColonne(); j++){
//if(m1.exist(i,j))
cout<<m2.getImmagine(i,j);
}
cout<<endl;
}
m2.inserisci(i1, 0, 0, &m2.immagini);
m2.inserisci(i2, 0, 1, &m2.immagini);
m2.inserisci(i3, 1, 0, &m2.immagini);
m2.inserisci(i4, 4, 4, &m2.immagini); //HERE IS WHERE I GET THE ERROR
cout <<"Stampa mosaico: "<<endl;
for (int i=0; i < m2.getRighe(); i++) {
for (int j=0; j < m2.getColonne(); j++){
cout<<m2.getImmagine(i,j);
}
cout<<endl;
}
}
By the way, this was a Java exercise and I tried to do it in C++. Thanks in advance!
Before I'll get to the details of the issues, let me first state that there are a lot of things in the code I'd do differently. Most prominently, I'd probably use a flat vector<Image> for storage instead of a vector<vector<..>>. But such things are better suited for CodeReview in my opinion (once the code is working).
The biggest problems in the OP's code are within the implementation of the inserisci function:
void Mosaico::inserisci(Immagine imm,int r, int c,
vector< vector<Immagine> >* immag) {
if(r < (*immag).size() && c < (*immag)[0].size()){
(*immag)[r][c]=imm;
}
This part is fine, if we assume that (*immag)[i].size() is the same for all i in [0, (*immag).size()). Let us call this assumption A. The [x, y) notation stands for a half-open-on-right interval (x is within that interval, y is not). Note that you can replace (*e).m with e->m, which I'll do in the following.
The assumption A is a class invariant: after every member function (except for the destructor), this class invariant must hold. Continuing with the inserisci function:
else if(r>=(*immag).size() && c>=(*immag)[0].size()){
(*immag).resize(r);
The *immag vector now has r elements. This is insufficient if you want to access the rth element, since indexing starts with 0. You need to have at least r+1 elements. Replace the above resize with:
int newRowCount = r+1;
(*immag).resize(newRowCount);
Continuing with the OP's function:
for(int i=0; i<r; i++){
This has the same off-by-one bug: replace r with newRowCount, or simply immag->size().
for(int i=0; i<immag->size(); i++){
Continuing with the OP's function:
for(int j=(*immag)[0].size(); j<c; j++){
(*immag)[i].insert((*immag)[i].begin()+j, imm);
}
}
With the above resize, we have added newRowCount - immag->size() new elements to the immag vector. Those new elements are vectors of the size 0. To be able to access the cth element of such a vector, we need to add at least c+1 elements to it.
The value of (*immag)[0].size() however changes after the first iteration of the outer loop such that (*immag)[0].size() == c for the remaining (*immag)[i] elements where i is in [1, newRowCount). This code won't add any new columns to those rows. A simple fix is:
int newColumnCount = c+1;
for(int j=(*immag)[i].size(); j < newColumnCount; j++){
(*immag)[i].insert((*immag)[i].begin()+j, imm);
}
}
(*immag)[r][c]=imm;
}
A note related to code review: You can very easily resize the inner elements as well, using the resize-overload which takes an additional argument:
(*immag)[i].resize(newColumnCount, imm);
Continuing with the OP:
else if(r>=(*immag).size() && c<(*immag)[0].size()){
(*immag).resize(r);
This suffers from the same off-by-one bug again. You need to have at least r+1 elements to access the rth element in the following
(*immag)[r][c]=imm;
}
And in the following piece of code, the same issues appear as in the second branch (that is, (*immag)[0].size() instead of referring to the current element's size, and j < c instead of j < newColumnCount).
else if(r<(*immag).size() && c>=(*immag)[0].size()){
for(int i=0; i<(*immag).size(); i++){
for(int j=(*immag)[0].size(); j<c; j++){
(*immag)[i].insert((*immag)[i].begin()+j, imm);
}
}
(*immag)[r][c]=imm;
}
}

Nested for loop filling an array

I am trying to create a nested for loop that fills in values in an array from 1 to 20.
IE) array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
int array[20];
for(int i = 0; i<21; i++)
{
for(int j =1; j<21; j++)
{
array[i] = j;
cout<< array[i];
}
}
Supposedly, The array index should count up with "i", and should be equated to "j" which is also counting up. The array element is printed to the console as it is filled.
I expected 1 -20 to be printed out once, but when I run the code, 1-20 prints out multiple times. Can someone tell me the problem? Thanks!
Your outer for loop runs 21 times, your inner for loop runs 20 times each of the outer for loop iterations, so you have a total of 21 * 20 = 420 print statements.
You can simply do
for(int i = 0 ; i < array.length ; i++)
{
array[i] = i + 1;
cout << array[i] << endl;
}
If you look at your array when you're done, it will also be just a series of 20s. The first loop is saying "do this 20 times" and then the second loop is saying "set and print the value of that array element 20 times." What you need to do is include a check for whether you're assigning the correct j value to the correct array[i] value, and only set the value in that case. Something like:
if (j == i + 1) array[i] = j;
Why do you need a nested loop?
for(int i = 0; i<20; i++)
{
array[i] = i + 1;
cout<< array[i];
}
yes, you have two loops when you only need one:
for(int i = 0; i<21; i++)
{
array[i] = i + 1;
cout<< array[i];
}
In order to fill the array and to print the result you just need two simple for loops
for(int i = 0; i<20; i++)
{
array[i] = j;
}
for(int j =0; j<20; j++)
{
cout<< array[i];
}
The nested loop that you created above will do exactly what you described.
For each loop of the outer for loop it will execute the full 20 loops of the inner loop.
so in total you will execute it 21 * 20 times.
Also be careful with your index. You want to start with int i = 0 to i < 20 which loops exactly 20 times.
I don't know why you are attempting to print a single element in you array, but it isn't necessary to use nested loops here; in fact, a loop isn't required at all:
// vector version
std::vector<int> vec(20);
std::iota(vec.begin(), vec.end(), 1);
// array version
int arr[20];
std::iota(std::begin(arr), std::end(arr), 1);
If you want to print out the whole array after you've initialized it:
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, "\n"));
I see a lot of people answered about this question, so I will not repeat them, I'll just mention that you are writing outside the array size.
if you have int array[20], you should loop
for(int i = 0; i<20; i++)
the last index is 19
The outer loop 21 times repeats the inner loop
for(int i = 0; i<21; i++)
{
for(int j =1; j<21; j++)
{
array[i] = j;
cout<< array[i];
}
}
The inner loop does the same operation that is assigns elements of the array sequantial numbers. Moreover your code has a bug because due to the outer loop youare trying to access element array[20] that does not exist, because if the array was defined as
int arrat[20];
then the valid indicies are 0 - 19.
That do not bother about writing correctly required loop or loops you could use standard algorithm std::iota
For example
#include <iostream>
#include <numeric>
#include <iterator>
#include <algorithm>
int main()
{
const size_t N = 20;
int array[N];
std::iota( std::begin( array ), std::end( array ), 1 );
std::copy( std::begin( array ), std::end( array ), std::ostream_iterator<int>( std::cout, " " ) );
}
Or instead of the algorithms you could use the range based for statement. For example
#include <iostream>
int main()
{
const size_t N = 20;
int array[N];
int i = 1;
for ( int &x : array )
{
x = i++;
std::cout << x << ' ';
}
}
If you really want to use nested solution, (for example game board coordinates) then this is my solution.
// nesting arrays for example game board coordinates
#include <iostream>
int main(){
int x = 20;
int y = 40;
int array[x][y];
// initialize array of variable-sized.
for(int i = 0; i < x; ++i){
for(int j = 0; j < y; ++j){
array[i][j] = 0; // or something like i + j + (i * (y-1)) if you wish
// and send it to cout
std::cout << array[i][j] << " ";
}
std::cout << std::endl;
}
//notice, that when sent to cout like this, x and y flips on screen, but
//logics of coordinates is ok
// and then do something usefull with it
return EXIT_SUCCESS;
}
int size = 20;
for (int i = 0; i < size; i++)
{ int array[i];
array[i] = i + 1;
cout << array[i]<< " ";
}
You could populate your array with 1 for loop, and gauge the size of your array like stated above.

Which is the fastest way to return the number of different rows in a matrix A?

If i have the following matrix A:
A = {1,2,3}
{7,9,1}
{5,3,2}
how i can easily return the number of different rows in the Matrix? In this case the output must be : "3"
i tried to make a function "rows":
void rows (int a[N][N], int row[N], int x){
for (int i=0;i<N;i++){
row[i]=a[x][i];
}
}
then, with the function "check" i tried to check if the rows are different:
int check ( int a[N][N])
{
int row1[N];
int row2[N];
int j=0;
rows(a,row1,j);
rows(a,row2,j+1);
int count = 0;
for ( int i=0; i<N; i++){
for ( int j=0; j<N; j++){
if ( row1[i] != row2[j]){
count++;
}
}
}
return count;
}
but return the wrong number , any suggestions ?
Your algorithm is entirely wrong. With an added break it "works" when all rows are different, but it breaks when some of the rows are the same. It counts the number of rows such that there exists another row that's different from it. For example, if you run it on
1 2 3
4 5 6
1 2 3
you will get an answer 3, but you should get a 2.
The algorithm should go like this:
Assume that all rows are distinct (result = N)
For each row i, look at the rows below it
If any of the rows j below the row i is equal to row[i], decrement the result and break out of the inner loop
At the end of the outer loop, result contains your answer.
Implement a 'CompareRows' functor as a predicate for set. Then, all you need to do is --
typedef vector<int> Rows;
set<Rows, CompareRows> UniqRows;
for ( int i = 0 ; i < N ; ++i )
UniqRows.insert(Rows(a[i], a[i] + N));
UniqRows.size();
try to add inequality variable into:
int count = 0;
for ( int i=0; i<N; i++){
inequalty=0;
for ( int j=0; j<N; j++){
if ( row1[i] != row2[j]){
inequality=1;
break; //this makes even faster
}
}
if(inequality!=0)count++;
}
even a single element's inequality makes the row inequal right?