C programming and array ,matrix manipulation - c

I am trying to take an online test on techgig.com .
The problem is to find the minimum path from top left of the matrix to the bottom right.
I am trying to code this using C language.
The minimumcost function is already given as and I am not allowed to change this .
char* minumumcost(char* input1[],int input2)
where input1 is the matrix and input2 is the number of rows in matrix.
However with my limited knowledge of C , I only know how to manipulate a matrix when it is declared as a two dimensional array.
With two dimensional array I intend to do the following operation.
Here the cost matrix is cost[10][10]
\
while(point1!=n && point2!=n)
{
if(cost[a][j+1]<cost[a+1][j] && cost[a][j+1]<cost[a+1][j+1])
{
min=cost[a][j+1];
s[k]='R';
k++;
j++;
point1=a;
point2=j;
}
else if(cost[a+1][j]<cost[a+1][j+1] && cost[a+1][j]<cost[a][j+1])
{
min=cost[a+1][j];
s[k]='B';
k++;
a++;
point1=a;
point2=j;
}
else if(cost[a+1][j+1]<cost[a+1][j] && cost[a+1][j+1]<cost[a][j+1])
{
min=cost[a+1][j];
s[k]='D';
a++;
j++;
k++;
point1=a;
point2=j;
}
}
\
An example shows that the input to the matrix is given in this form.
{5#2#3#2,8#5#5#3,1#4#7#6,3#3#6#5},4
where 4 is the no of rows and the remaining is the elements of the row .
The question is how do I do this by using input1[] ?
Please help me soon.
The test has a time limit.

The function accepts an array of char*. Note that, in C, arrays and pointers can be used interchangably most of the time.
If you declared a pointer like char* p; you could use it just like an array: p[5]. So in your case, char* input[] is quite the same as an array of arrays of char: input[2][5] will take element #2 from the array (yielding a char*!) and from that element #5.
Or, even more explicitly, you could as well write
char* row = input[2];
char element = row[5];
Yet, how many elements each row of the matrix will have cannot be told from what you posted. Is it a square matrix, are the rows represented as \0 terminated strings? You'll have to check the test question for that info.

Related

I'm not able to find what is causing the segmentation error in my C++ code

I have a C++ program where I have to rotate the array clockwise according to the given number of elements to be rotated (x). For example if the input array is
[1,2,3,4,5]
given that 2 elements (denoted as x) must to rotated.
The output array should be
[3,4,5,1,2]
Code:
#include <iostream>
#include<algorithm>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
int n,x;
cin>>n>>x;
int a[n],b[x];
for(int i=0;i<n;i++){
cin>>a[i];
}
copy(a,a+x,b);
copy(b,b+x,a+n);
n=n+x;
for(int i=x;i<n;i++){
cout<<a[i]<<" ";
}
}
return 0;
}
What I'm doing here is that I copy the given number of elements to a new array. Later copy them back to the original array starting from 'n'. So my array will look like [1,2,3,4,5,1,2].
Later I'm printing out the array starting from the index 'x'. So that my array will look like [3,4,5,1,2].
I'm able to compile the program and I'm getting the output. But while submitting the code in a website called GeekforGeeks its complier is throwing out a Segmentation Fault (SIGSEGV).
This
int a[n],b[x];
is not standard c++. See here for details: Why aren't variable-length arrays part of the C++ standard? . Use std::vector for dynamic arrays.
Then here:
copy(a,a+x,b);
you use x but the size you used for a was n not x. Depending on your input this may acces the array out-of-bounds.
Next, here:
copy(b,b+x,a+n);
you try to copy to a+n but already a+n is beyond the last element of a. Arrays have fixed size, also n=n+x; wont help to change that.
To rotate elements of an array (or std::vector) you can use std::rotate.
Problem 1
The line
copy(a,a+x,b);
does not do what you want to do. It copies the first x elements of a to b, without an offset. If x is 2, that is equivalent to:
b[0] = a[0];
b[1] = b[1];
You need something that will do:
b[0+x] = a[0];
b[1+x] = a[1];
...
b[n] = a[n-x-1];
To achieve that, you need to use:
std::copy(a, a+(n-x), b+x);
Problem 2
The line
copy(b,b+x,a+n);
is notright.
You want to copy from a to b, not from b to a.
Using a+n immediately results in accessing the array using out-of-bounds indices, which causes undefined behavior.
The offsets used in that call don't make sense at all.
After the first line of std::copy is executed, you need something what will do the following:
b[0] = a[n-x];
b[1] = a[n-x+1];
...
b[x-1] = a[n-1];
To achieve that, you need to use:
std::copy(a+(n-x), a+n, b);
Arrays must have determined size
some compilers accept your code but other don't
so try to use pointers instead

Sorting integer array by ascending order, segmentation fault: 11

The function is suppose to sort an array of random integers by ascending order. I found a method for solving this problem, the bubble sort, swaping a by b if b < a. However, my implementation, or the lack of it, keeps returning a segmentation fault: 11. Could it have something to do with the parameter "int *tab" or subscripts I'm using during the swaping of elements?
void ft_sort_integer_table(int *tab, int size)
{
int i;
int j;
int t;
i = 1;
j = 0;
t = 0;
while (tab[j] != '\0')
{
if (tab[i] < tab[j])
{
t = tab[i];
tab[i] = tab[j];
tab[j] = t;
}
i++;
j++;
}
}
Unless you are guaranteed beforehand that the value 0 terminates your buffer and doesn’t appear elsewhere in the array (like you are with null terminated strings) you can’t test for tab[i] being zero to determine that you have reached the end of the array. Your function takes size as a parameter too; why not use that?
EDIT: Also, no sorting algorithm runs in O(n). Bubble sort, which looks like what you’re trying to implement, requires two nested loops.
Skipping the correctness of this implementation of the sorting algorithm (as it seems wrong) the segmentation is caused by the null termination check that you are doing. The NULL('\0') character is specified for strings, or char array types in C programming language, and it is used to signal their termination. It doesn't work with int type arrays. You should be using the size argument for iterating the array.
You do not use the size parameter. Instead you are trying find the null-terminator which int array is not supposed to have (unlike C-string). So in case you have to compare j with size and keep swapping till the array is fully sorted.
Also, it is better of using size_t size instead of int size in order to stay pedantic.
You pass an array and a size to your sorting function but do not use the size anywhere so potentially i and j could go out of bounds causing undefined behavior.
An int array can contain 0s so you need to have other criteria for when your sorting is finished. E.g. when you go through all the elements in the array [0..size] and do not do a swap - then it is sorted.
Firstly, your while loop logic is wrong. The character '\0' refers to the null character at the end of string. This doesn't make sense if you compare it with int type.
Secondly, the logic you implemented is comparing side by side elements of an array and not a single element with all others and placing it. I would recommend you study bubble sort. Geekforgeeks is the best source for cse guys. Hope it solves. Cheers !! Feel free to ask questions

Comparing elements from two 2d-arrays in C without strcmp

I am creating a spell-checker in C. I have a dictionary array which is a 2d array. So each word in the dictionary takes a row in the 2d array. In the same way, my input array is also a 2d array. I want to check the spelling of the rows/words in my input array. I cannot use strcmp
An example of input array
['boy','girll','.','friend',' ']-can contain spaces,punctuation and words. We only care about spelling words
if a punctuation/space is compared against a word,we ignore it and move onto the next word.
example of dictionary
['boy','girl','cow'...]-all are words
My code is:
for (int a = 0; a < MAX_INPUT_SIZE + 1; a++)
{
for (int b = 0; b < MAX_DICTIONARY_WORDS; b++)
{
if(tokens[a]==dict_token[b])
{
printf("correct");
}
else
{
printf("wrong");
}
}
}
The output is all "wrong". Though 5 out of the 6 word input should be correct.
Every test returns false because the comparison you're using,
if(tokens[a]==dict_token[b])
is comparing two pointers that are never going to point at the same address, because, the tokens you are testing are in a completely separate bit of memory to the dict_token dictionary that you are comparing them with.
You need to pass the two pointers tokens[a] and dict_token[b] to a comparison function that will perform a letter-by-letter comparison, and which will return one value when it finds a difference between them, and another when it gets to the end of both without finding a difference. In other words, you need to write an implementation of strcmp.

verify each element to one other in a array pointer

C Experts,
I have an array of pointers to strings. I need to compare each array element with all other array elements and throw error if they are same. Here is the piece of code I have written and got stuck. Please help me.
# define FOUND 1
# define NOTFOUND 0
int k,flag,a;
char cmp_string[10]; //used to get one array element to compare with all other array elements
char *values[]={010,020,030,040}; //valid case that's how it should be
char *vales[]={010,020,020,030}; wrong or throw error because in array i should have only unique values
int size=4;
for(k=0; k<=size;k++){
strcpy(values[k],cmp_string);
flag=NOTFOUND;
int counter=k+1;
for(int n=counter;n<=size;n++)
{
a=((strcmp(values[n],cmp_string) || (strcmp(values[k-1],cmp_string)))
// stuck here what if k value is 2 I wont be able to compare with zero or first element of array.
if(a==0){
throw error same name for the operation
flag=FOUND;
break;
}
}//for int n;
}//for int k;
if(flag==NOTFOUND){
True or PASS
}
}
Quick solution: sort the array (using e.g. the builtin qsort function), then scan it comparing adjacent elements; if two are the same, you have a repetition.
You can also know before completing the sort that you have duplicates if in the comparison function you find that the two compared items are the same.
If I understand your question correctly, you're trying to turn strcmp into something that returns nonzero if the strings are the same and zero otherwise:
a = (strcmp(whatever) != 0) || (strcmp(whatever else) != 0);

"Direction" of bidimensional arrays in C

as a C newcomer I'm a bit confused about bidimensional arrays.
If I want to represent a matrix of 3 rows and 5 columns, I guess the correct declaration is:
char a[3][5];
So, is this an array of 3 pointers to 5 arrays of chars or what?
How come whenever I try to cycle through it like the following it seems to read the wrong results?
int x, y;
for( x=0; x<3; x++ ){
for( y=0; y<3; y++ ){
printf( "%c", a[x][y] );
}
}
Are the following equivalent and correct ways to initialize it?
char a[3][5] = {
{1,0,0,0,1},
{1,0,0,0,1},
{1,0,0,0,1},
};
char a[3][5] = {1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1};
Thanks for any eventual upcoming explanation.
EDIT
Sorry the typos, the code is not copied. By the way, I keep on having them read like they where read in a vertical way, not in a horizontal one.
Also in the example in this tutorial http://www.cplusplus.com/doc/tutorial/arrays/ it reads the array in a way that is not streight-forward to me as it seems to work on a 5x3, HeightWidth, yx, colsrows structure instead of a 3x5, WidthHeight, xy. rowscols one:
#define WIDTH 5
#define HEIGHT 3
int jimmy [HEIGHT][WIDTH];
int n,m;
int main ()
{
for (n=0;n<HEIGHT;n++)
for (m=0;m<WIDTH;m++)
{
jimmy[n][m]=(n+1)*(m+1);
}
return 0;
}
Just for what it is and what not.
char a[3][5];
There are no pointers involved. A multi dimensional array like that is an array of arrays of .... and so on. In your case, you have an array of 3 arrays of 5 characters. It becomes clearer when you do it with typedefs.
typedef char T[5];
T a[3];
No pointers are involved whatsoever. If you want to access the first array of those 3 ones, you can do so:
a[0];
And it will give you back an object of type char[5]. Normally, you don't notice that because normally you index all dimensions. So the array that's returned by a[0] is subscript by the next index, for example a[0][1]. The [1] will be applied to the array that was returned by a[0], which as we have figured out earlier has type char[5].
So, is this an array of 3 pointers to 5 arrays of chars or what?
Let's create that type and see how it's different to the above. Creating it is simple, once you get the basic declarators:
Creating a pointer: *D
Creating an array: D[N]
D is just an existing another declarator. So now let's go on. First you say array of 3 pointers to 5 arrays of chars.... I think you meant array of 3 pointers to arrays of 5 chars. First, array of 5 is created like
D1[5]
Now, let's replace D1 by a pointer to declarator:
(*D2)[5]
We had to insert parentheses, because the subscript operator [N] binds better than the dereference operator *, and it would otherwise be read as *(D2[5]) which isn't what we want. Now we have pointer to array of 5.
Now let's do the array of 3. Replacing D2 by D3[3] yields this:
(*D3[3])[5]
Great, now we have got a array of 3 pointer to array of 5. Just putting the base type that that declarator appertains to yields the complete declaration:
char (*D3[3])[5];
That's of course a complete different thing :) You could use it to store pointers to your other array which was of type array of 3 arrays of 5 char. Let's store a pointer to the first sub-array of a into D3[0]. We figured out earlier that a[0] has type char[5]. We can store a pointer to that array into D3[0], because D3 is an array of pointers to char[5], what a coincidence!
D3[0] = &a[0]; // works!
I hope this little exercise has shown you some of the relations between pointers and arrays. Cheers!
I see a couple of problems with your code. First (copied from above):
int x, y;
for( x=0; x<3; x++ ){
for( x=0; x<3; x++ ){
printf( a[x][y] );
}
}
In your inner-loop, it looks like you want to use y instead of x, and you want y to go from 0..5. Currently, you are repeating the variable x. Also, you have a problem with your printf() statement. Here's some corrected code:
int x, y;
for( x=0; x<3; x++ ){
for( y=0; y<5; y++ ){
printf("%d\n", a[x][y] );
}
}
Second, when you initialize your array, your code is almost correct. Here's the corrected version:
char a[3][5] = {
{1,0,0,0,1},
{1,0,0,0,1},
{1,0,0,0,1}
};
(I removed the , after the very last "row" of data - that was a syntax error.)
The 2nd syntax you posted is incorrect (the one with no curly braces).
You've got wrong results because you're using x twice (looks like a copy/paste error). Try
int x, y;
for (x = 0; x < 3; x++) {
for (y = 0; y < 5; y++) {
printf("%c", a[x][y]); // Emil H says "%d" might be more useful
}
}
Edit: I'm not sure what's confusing about that tutorial. It's precisely equivalent to your code, except instead of printing the array, it's setting each element to (row*column) (where both row and column are one-based, hence the +1's).
The image that is in the tutorial is a great representation of the data:
alt text http://www.cplusplus.com/doc/tutorial/arrays/bidimensional_arrays3.gif
From the example, the nested for loops traverses across (left -> right) the array row by row and fills in a value for each column.
The small errors like using "%c" when you probably want "%d" and such are not what you really want to get answered I humbly think. You say you are a bit confused about arrays and also mentions that you expect to see pointers as the array-elements of the array containing arrays. You
The last comma in your definition of the array-of-arrays is NOT a syntax error. It is permitted as of C99.
What really will clear up things is to know that arrays are not pointers. It is true that an array name may be used as a constant pointer (to the first element) and that pointers can be indexed like they were arrays. This does not mean, however, that arrays and pointers are the same. They are not.
You ask about what the symbol "a" in your program actually is. It is an array of arrays. The memory layout may be visualized like a long line cut in three parts but still on a continuous line. Then cut each of these in five parts in the same manner. When addressing one element you must use two indexes; first for which five-element-array you want and then for which fifth of this element you want.
The memory layout is not like a grid of rows and columns. The memory is addressed by one scalar, so its linear. Pointer arithmetic may be the next thing you could look into, and see how an increment on a pointer works.
int x, y;
for( x=0; x<3; x++ ){
for( x=0; x<3; x++ ){
printf( a[x][y] );
}
}
You need to change the 2nd for loop to refer to 'y' instead of 'x'.
hope that helps.
You're using printf in the wrong way. Try:
printf("%d", a[x][y]);
I'm not sure whether you'll want to use %c or %d. If you want to print the number, use %d. If you want to print an actual character, use %c.
char a[3][5];
So, is this an array of 3 pointers to
5 arrays of chars or what?
Yes, that's what it is. Although you could also manipulate it as a consecutive set of 15 chars.
By convention, most people would think of it as representing a matrix with 3 rows and 5 columns (I think), but there's nothing about the data structure itself that requires that. You could just as easily use it to represent 5 rows and 3 columns. Or 3 sets that each include 5 elements but have no meaningful relationship to each other at all.
A particular library for doing matrix manipulation would have a convention for this.

Resources