I looked everywhere and I could not find a concrete answer that suits my needs. I want use this type of format to sort a more complicated array than this example. It compiles, but when I run it I get the terminated by signal SIGSEV (address boundary error).
A simple example of what I am trying to do:
string array[] = {zipper, bad, dog, apple, car};
string temparray[5];
int counter = 0;
for(int i = 0; i < 5; i++){
for(int x = 0; x < 5; x++){
if(array[i] > array[x]){
counter++;
}
}
temparray[counter] = array[i];
}
for(int y = 0; y < 5; y++){
array[y] = temparray[y];
}
What seems to be the problem?
You never reset counter. Suppose that your array is {5,4,3,2,1}. Then after the first iteration of the for loop, you'd have counter=4. After the next iteration of the inner for loop, counter would be 7, and you'd be trying to access the 7th element in temparray on your line
temparray[counter] = array[i];
but temparray is only 5 elements long. I don't offhand know how the > and < operators work for std::string's, but I'd bet oaks to acorns this is your problem.
You can fix this just by adding
counter=0;
directly after the aforementioned line:
temparray[counter] = array[i];
or by initializing it to zero at the start of the loop, or declaring it in the loop or what have you.
Related
I am trying to make a program that sorts an array without using the sort function (that won't work with objects or structs). I have made the greater than one work, but the less than one keeps changing the greatest element in the array to a one and sorting it wrong, and when used with the greater than function, the first element is turned into a large number. Can someone please help me fix this or is it my compiler.
void min_sort(int array[], const unsigned int size){
for(int k = 0; k < size; k++) {
for(int i = 0; i < size; i++) {
if(array[i] > array[i+1]){
int temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
}
}
}
}
You are not looping correctly. Looks like you are trying bubble sort which is:
void min_sort(int array[], const unsigned int size){
for(int k = 0; k < size; k++)
for(int i = k+1; i < size; i++)
if(array[i] < array[k]){
int temp = array[i];
array[i] = array[k];
array[k] = temp;
}
}
void min_sort(int array[], const unsigned int size)
{
for(int i=0;i<size-1;i++)
{
for(int j=0;j<size-1-i;j++)
{
if(array[j]>array[j+1])
{
swap(array[j] , array[j+1]);
}
}
}
}
I see that you are trying to implement the bubble sort algorithm. I have posted the code for bubble sort here. In bubble sort you basically compare the element at an index j and the element next to it at index j+1. If array[j] is greater than array[j+1] , you swap them using the swap() function or by using the temp method. The outer loop will run size - 1 times , and the inner loop will run size - 1 - i times because the last element will already be in place.
For Example we have an array of size 4 with elements such as :
array[i] = [100,90,8,10]
The bubble sort will sort it in the following steps :
90,100,8,10
90,8,100,10
90,8,10,100
8,90,10,100
8,10,90,100
8,10,90,100
See, the use of size-1-i . You can see the nested loop runs less number of times in each iteration of the outer loop.
There is only one mistake that your 2nd loop condition should be: i < size -1.
So it should be:
for (int i = 0; i < size -1; i++)
Your attempt at bubble sort is basically correct, you just have an out of bounds issue with your inner loop. During the inner loop's last run, i == size - 1, therefore i + 1 is equal to size, thus data[i+1] is out of range. Simply change the condition of your for to be i < size - 1.
Working example: https://godbolt.org/z/e5ohWPfTz
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.
I have a game that creates a random string of letters and then inputs it to a 2d vector. I was oringally using an array and it filled the array with random letters as it should, but the array was giving me some problems. My friend suggested a 2d array.
Here is the print function that gives me the error that actually causes a break in the program:
const vector<vector<char>>& Board::get_board()
{
for (int i = 0; i < 16; i++)
{
letters.insert(letters.begin(), 1, random_letter());
}
uppercase(letters);
random_shuffle(letters.begin(), letters.end());
int counter = 0;
for (size_t i = 0; i < 4; i++){
for (size_t j = 0; j < 4; j++)
{
board[0].push_back(letters[counter++]);
}
}
I keep getting the array to fill the first row, but then it throws an exception. I'm not sure what the exception is, but when I try to move forward, it tells me the code exited with exception 0 and points to the board[][] line in the print method. I don't think the second vector is being filled. How can I do this? Should I make another temp vector, or use a pair method? I tried the pair method before without much success.
I just changed the 0 to i and indeed, that solved the issue. Thanks! I think that I was thinking the vector would just push to the front counter number of times, not that we had 2 dimensions where the board[i] set the row. Thanks again. Silly error.
Your vector isn't being populated correctly in your get_board() method:
board[0].push_back(letters[counter]);
You're always pushing back onto the first element, but then you use it with the expectation that the board vector has 4 entries in it with the print() method. You also never increment counter and so you always push back the same letter...
Okay, based on comments, you've said you fixed how populate to something more like?
int counter = 0;
for (size_t i = 0; i < 4; i++){
for (size_t j = 0; j < 4; j++)
{
board[i].push_back(letters[counter++]);
}
}
I also don't see the point of the if statement in the print() method.
I have a MatrixGraph class with a member variable M that is of type vector<vector<double> >. I have a constructor that takes in an unsigned, and makes a NxN matrix from that input, and I want to initialize it to zero. The problem is when I run my code the debugger kicks in when I am trying to assign stuff. I have tried to methods, the first:
MatrixGraph::MatrixGraph(unsigned num_nodes) {
for(int i = 0;i < num_nodes;i++) {
for(int j = 0;j < num_nodes;j++) {
M[i][j] = 0.0;//breaks on this line
}//end i for loop
}//end j for loop
}
and the second method i tried i found on here but that didn't work either:
MatrixGraph::MatrixGraph(unsigned num_nodes) {
for(int i = 0;i < num_nodes;i++) {
M[i].resize(num_nodes);//breaks on this line
}
}
i commented on here where the last line on the call stack is before i get errors. The next line after that on the call stack shows me the class vector and is saying that my Pos is greater than the size of my vector. I assume that this is a size zero matrix, but i don't know why i cant make it bigger. Any suggestions?
Thanks!
The reason your code is failing is that you cant use the [] operation on a vector before that element exists. The usual way to add a value to a vector is to use push_back.
If you want to initialize to 0 you want assign(). Resize the outer vector to the required size and then assign each of the inner vectors with 0
M.resize(num_nodes);
for(int i = 0;i < num_nodes;i++)
{
M[i].assign(num_nodes,0.0f);
}//end i for loop
This can also be done. It is cleaner code but a tad less efficient since it makes 1 extra vector object.
vector<double> temp;
temp.assign(num_nodes,0.0);
M.assign(num_nodes,temp);
or just
M.assign(num_nodes,vector<double>(num_nodes,0.0));
neatest one(courtesy #Mike Seymour) would be
MatrixGraph(unsigned num_nodes)
: M(num_nodes, vector<double>(num_nodes,0.0))
{}
(thanks Mike Seymour for the constructor syntax)
What you are doing here is initializing the outer vector with a temp vector full of 0.0s
You need to populate your vector M with data: M.resize(num_nodes)
This should do it:
MatrixGraph::MatrixGraph(unsigned num_nodes)
{
M.resize(num_nodes);
for(int i = 0;i < num_nodes;i++)
{
M[i].resize(num_nodes);
for(int j = 0;j < num_nodes;j++)
{
M[i][j] = 0.0;
}//end j for loop
}//end i for loop
}
I tried to write a countingsort, but there's some problem with it.
here's the code:
int *countSort(int* start, int* end, int maxvalue)
{
int *B = new int[(int)(end-start)];
int *C = new int[maxvalue];
for (int i = 0; i < maxvalue; i++)
{
*(C+i) = 0;
}
for (int *i = start; i < end; i++)
{
*(C+*i) += 1;
}
for (int i = 1; i < maxvalue-1 ; i++)
{
*(C+i) += *(C+i-1);
}
for (int *i = end-1; i > start-1; i--)
{
*(B+*(C+(*i))) = *i;
*(C+(*i)) -= 1;
}
return B;
}
In the last loop it throws an exception "Acces violation writing at location: -some ram address-"
Where did I go wrong?
for (int i = 1; i < maxvalue-1 ; i++)
That's the incorrect upper bound. You want to go from 1 to maxvalue.
for (int *i = end-1; i > start-1; i--)
{
*(B+*(C+(*i))) = *i;
*(C+(*i)) -= 1;
}
This loop is also completely incorrect. I don't know what it does, but a brief mental test shows that the first iteration sets the element of B at the index of the value of the last element in the array to the number of times it shows. I guarantee that that is not correct. The last loop should be something like:
int* out = B;
int j=0;
for (int i = 0; i < maxvalue; i++) { //for each value
for(j<C[i]; j++) { //for the number of times its in the source
*out = i; //add it to the output
++out; //in the next open slot
}
}
As a final note, why are you playing with pointers like that?
*(B + i) //is the same as
B[i] //and people will hate you less
*(B+*(C+(*i))) //is the same as
B[C[*i]]
Since you're using C++ anyway, why not simplify the code (dramatically) by using std::vector instead of dynamically allocated arrays (and leaking one in the process)?
std::vector<int>countSort(int* start, int* end, int maxvalue)
{
std::vector<int> B(end-start);
std::vector<int> C(maxvalue);
for (int *i = start; i < end; i++)
++C[*i];
// etc.
Other than that, the logic you're using doesn't make sense to me. I think to get a working result, you're probably best off sitting down with a sheet of paper and working out the steps you need to use. I've left the counting part in place above, because I believe that much is correct. I don't think the rest really is. I'll even give a rather simple hint: once you've done the counting, you can generate B (your result) based only on what you have in C -- you do not need to refer back to the original array at all. The easiest way to do it will normally use a nested loop. Also note that it's probably easier to reserve the space in B and use push_back to put the data in it, rather than setting its initial size.