I'm trying to create a function in C that will swap the indexes of my 2D array by replacing the last row index with the first row index on each iteration until the whole array is completely reversed. For example, the given sample of strings:
I am human
hello world
et is real
i am the knight
should output:
i am the knight
et is real
hello world
I am human
using my swap function. Instead the output I get (last string gets cut off) is this:
Ih am human
eello world
it is real
The function I've whipped up, looks like this:
void swap(char array[][COLS], int start, int end)
{
for(int i = 0; i >= ROWS; i++)
{
int temp = array[start][i];
array[start][i] = array[end][i];
array[end][i] = temp;
end--;
}
}
I've defined ROWS and COLS to be of size 100. What am I doing wrong and how do I rectify this?
To get the desired output, you do not want to use any sort of assignment. Assignment, as you may already know, refers to setting one piece of memory to be equal to another. In other words, copying. These three lines in your code are all assignment and cause copies to be made:
int temp = array[start][i];
array[start][i] = array[end][i];
array[end][i] = temp;
The following method will require that your string array be defined as follows:
char** array = {
"I am human",
"hello world",
"et is real",
"i am the knight"
};
Since all you want to do is print the contents in reverse order, you simply need to start at the end row, and work your way back to the beginning row. If this is your printing function
void printStrings(char** array, int start, int end)
{
while(start!=end)
{
printf("%s\n",array[start]);
++start;
}
}
You would call it like this to print the strings in normal order:
printStrings(array,0,3);
Or
printStrings(array,0,sizeof(array)-1);
And to print it in reverse order, you would need a different function:
void printStringsReverse(char** array, int end, int start)
{
while(end!=start)
{
printf("%s\n",array[end]);
--end;
}
}
And you would call this function like this:
printStringsReverse(array,3,0);
Or
printStringsReverse(array,sizeof(array)-1,0);
No assignment is needed. No copies are made. No malloc is used. You are simply printing what is already there so there is no need to move anything around. There are, of course, many ways that you could write these functions. In fact there is a way that you could write both functions to just be one function. But this is a simple method that will have very little overhead.
Related
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.
It's quite a simple question, yet I cannot find an answer that works.
Take the following 2D array: int grid[4][4]. I could fill it with integers, so that visually, it could look something like:
1,0,0,5,0 0,0,0,6,7 3,0,0,0,7 2,0,0,0,9 4,0,0,2,0 (each segment a new row)
Now, what if I only wanted the data of one row, to be given as a standard array? The way I would of thought to do this would be: grid[0], which would give me 1,0,0,5,0.
However, this does not seem to work. Can anyone tell me how I can extract rows of data? Here is a code example
int grid[4][4];
//Add in some numbers, e.g.
grid[0][3] = 5;
//Get the first row
int* row1 = grid[0]; //I'm not sure about this
For instance, this example should set "row1" to "0,0,0,5,0"
I have the feeling I'm doing something awfully wrong here...
There is no error message, but it just gives "row1" a random string of integers instead, which are definitely not correct.
Remember, in an array declared int grid[4][4], you can only store four lots of four elements (sixteen total).
Your array, { 1,0,0,5,0 }, { 0,0,0,6,7 }, { 3,0,0,0,7 }, { 2,0,0,0,9 }, { 4,0,0,2,0 } is actually an int [5][5].
What you're doing is not wrong; row1 will be a pointer to the first item of grid[0]. If you wanted to print each element, that's a good start...
In a moment of clarity, you'll likely realise when I mention the word "loop"... You then need a "loop" to loop through each element of the row!
int *row = grid[0];
for (size_t x = 0; x < sizeof grid[0] / sizeof grid[0][0]; x++) {
printf("%d, ", row[x]);
}
putchar('\n');
I'm new to programming, currently learning C. I've been working at this problem for a week now, and I just can't seem to get the logic straight. This is straight from the book I'm using:
Build a program that uses an array of strings to store the following names:
"Florida"
"Oregon"
"Califoria"
"Georgia"
Using the preceding array of strings, write your own sort() function to display each state's name in alphabetical order using the strcmp() function.
So, let's say I have:
char *statesArray[4] = {"Florida", "Oregon", "California", "Georgia"};
Should I do nested for loops, like strcmp(string[x], string[y])...? I've hacked and hacked away. I just can't wrap my head around the algorithm required to solve this even somewhat efficiently. Help MUCH appreciated!!!
imagine you had to sort the array - think of each state written on a card. HOw would you sort it into order. There are many ways of doing it. Each one is called an algorithm
One way is to find the first state by looking at every card and keeping track in your head of the lowest one you have seen. After looking at each card you will have the lowest one. Put that in a new pile. NOw repeat - trying to find the lowest of the ones you have left.
repeat till no cards left in original pile
This is a well known simple but slow algorithm. Its the one i would do first
there are other ones too
Yes, you can sort by using nested for loops. After you understand how strcmp() works it should be fairly straight forward:
strcmp(char *string1, char *string2)
if Return value is < 0 then it indicates string1 is less than string2
if Return value is > 0 then it indicates string2 is less than string1
if Return value is = 0 then it indicates string1 is equal to string2
You can then choose any of the sorting methods once from this point
This site has a ton of great graphical examples of various sorts being performed and includes the pseudo code for the given algorithms.
Do you need "any" sorting algorithm, or an "efficient" sorting algorithm?
For simplicity, I can show you how to implement an easy, but not efficient, sorting algorithm.
It's the double for method!!
Then, with the same ideas, you can modify it to any other efficient algorithm (like shell, or quicksort).
For numbers, you could put arrays ir order, as follows (as you probably know):
int intcmp(int a, int b) {
return (a < b)? -1: ((a > b)? +1: 0);
}
int main(void) {
int a[5] = {3, 4, 22, -13, 9};
for (int i = 0; i < 5; i++) {
for (int j = i+1; j < 5; j++)
if (intcmp(a[i], a[j]) > 0) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
printf("%d ", a[i]);
}
}
The only thing that has changed now is that you have strings intead integers.
So, you have to consider an array of strings:
char *a[] = {"Florida", "Oregon", "Califoria", "Georgia"};
Then, you have to change the type of temp to char*,
and finally you put the function strcmp() instead of intcmp().
The function strcmp(s1, s2) (from < string.h >)
returns a number < 0 if s1 is a string "less than" s2, == 0 if s1 is
"equal to" s2, and > 1 else.
The program looks like this:
#include <stdio.h>
#include <string.h>
int main(void) {
char *a[] = {"Florida", "Oregon", "Califoria", "Georgia"};
for (int i = 0; i < 4; i++) {
for (int j = i+1; j < 4; j++)
if (strcmp(a[i], a[j]) > 0) {
char* temp = a[i];
a[i] = a[j];
a[j] = temp;
}
printf("%s ", a[i]);
}
getchar();
return 0;
}
Note that for the printf() sentence, we have changed "%d " by "%s ", in order to properly show strings.
Final comment: When you program a better algorithm, like quick-sort, it is enough that you change the comparisson function, because the algorithm it is the same, in despite of the type of data you are comparing.
Remark: I have used a "tricky" method. As you can see, I have defined the variable a as a pointer to string. The initializer has taken a constant array of strings and then initialized the variable a with it. The variable a now can be safely treated and indexed as an array of exactly 4 pointer-to-strings.
That is the reason why the "swap" works fine in the double-for algorithm: The memory addresses are swapped instead the entire strings.
Steps you likely should take:
Populate array with state names
Create method to swap two states in place in the array
At this point you have all the tools necessary to use strcmp to implement any sorting algorithm you choose
Most sorting methods rely on two things.
Being able to rearrange a list (i.e. swap)
Being able to compare items in list to see if they should be swapped
I would work on getting those two things working correctly and the rest should just be learning a particular sorting algorithm
Beware of a little headaching problem: Strings are sorted by ascii numeric representations, so if you sort alphabetically like this, any capital letter will come before a lowercase letter e.g. "alpha", "beta", "gamma", "Theta" will be sorted as:
Theta, alpha, beta, gamma
When it comes to the sample array you have listed here the simple algorithm mentioned earlier might actually be the most efficient. The algorithm I'm referring to is the one where you start with the first element and then compare it to the others and substitute with the smallest you find and then going to the next element to do the same only dont compare it to the already sorted elements.
While this algorithm has an execution time of O(n^2). Where n is the number of elements in the array. It will usually be faster than something like quick sort (execution time O(n*log(n)) for smaller arrays. The reason being that quick sort has more overhead. For larger arrays quick sort will serve you better than the other method, which if memory serves me right is called substitution sort although I see it mentioned as "double for" in a different answer.
This is for a Deal or No Deal game.
So in my main function I'm calling my casesort method as such:
casesort(cases);
My method looks like this, I already realize it's not the most efficient sort but I'm going with what I know:
void casesort(float cases[10])
{
int i;
int j;
float tmp;
float zero = 0.00;
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++)
{
if (cases[i] < cases[j])
{
tmp = cases[i];
cases[i] = cases[j];
cases[j] = tmp;
}
}
}
//Print out box money amounts
printf("\n\nHidden Amounts: ");
for (i = 0; i < 10; i++)
{
if (cases[i] != zero)
printf("[$%.2f] ", cases[i]);
}
}
So when I get back to my main it turns out the array is sorted. I thought void would prevent the method returning a sorted array. I need to print out actual case numbers, I do this by just skipping over any case that is populated with a 0.00. But after the first round of case picks I get "5, 6, 7, 8, 9, 10" printing out back in my MAIN. I need it to print the cases according to what has been picked. I feel like it's a simple fix, its just that my knowledge of the specifics of C is still growing. Any ideas?
Return type void has nothing to do with prevention of array from being sorted. It just says that function does not return anything.
You see that the passed array itself is affected because an array decays to a pointer when passed to a function. Make a copy of the array and then pass it. That way you have the original list.
In C, arrays are passed by reference. i.e. they're passed as pointer to the first element. So when you pass cases into your function, you're actually giving it the original array to modify. Try creating a copy and sorting the copy rather than the actual array. Creating a copy wouldn't be bad as you have only 10 floats.
Instead of rolling your own sort, consider using qsort() or std::sort() if you are actually using c++
There are 2 obvious solutions. 1) Make a copy of the array and sort the copy (easy, waste some memory, likely not a problem these days). 2) Create a parallel array of integers and perform an index sort, i.e., instead of sorting thing original, you sort the index and then dereference the array using the index when you want the sorted version, otherwise by the raw unsorted array.
Well, make a local copy of you input and sort it. Something like this:
void casesort(float cases[10])
{
float localCases[10];
memcopy(localCases, cases, sizeof(cases));
...
Then use localCases to do your sorting.
If you don't want the array contents to be affected, then you'll have to create a copy of the array and pass that to your sorting routine (or create the copy within the routine itself).
Arrays Are Differentâ„¢ in C; see my answer here for a more detailed explanation.
Is there anyway to test for the first empty value of a 2 dimensional int array in c?
In my current program, I used 2 for loops before the main program(while loop) to set all the values of my 2 dimensional array to -9999. Then inside my main while loop, I test for the first -9999 value and set it to a value, and then use break to exit from it.
Using this I managed to do my assignment, but I'm not very satisfied, as I think there might be a better solution.
Is there one?
EDIT: Code since you asked for it.
For loop outside while loop:
for(int x=0;x<ctr-1;x++)
{
for(int y=0;y<maxtrips;y++)
{
EmployeeKilos[x][y] = -9999; // Set all the kilos to -9999 to signify emptiness.
}
}
Inside my main while loop:
for(int x=0;x<ctr-1;x++) // and set it to the log kilometers
{
if(employeenames[x].EmployeeNumber == log.Record)
{
for(int y=0;y<maxtrips;y++)
{
if(EmployeeKilos[x][y] == -9999)
{
EmployeeKilos[x][y] = log.Kilometers;
break;
}
}
}
}
All my code: http://pastebin.com/Zb60mym8
As Dave said, checking for empty values cannot be made more efficient than linear time (O(n)), but my answer focuses on a solution that can prevent having to look for it in the first place.
In general you could iterate the matrix in row-major or column-major mode.
Effectively, you can use a single index that translates to a matrix cell like so
for (size_t i=0; i<ROWS*COLS; ++i)
{
int row = i / ROWS;
int col = i % ROWS;
// work with matrix[row][col]
}
This way you could just store and remember the value of i where you last found the first empty cell, so you don't have to restart from the beginning.
If you're not actually interested in row/col addressing, you could forget about those and just use an output iterator to track your current output location.
Here's a demo using 'iterator' style (borrowing from c++ but perfectly C99)
typedef int data;
typedef data* output;
output add_next(data matrix[ROWS][COLS], output startpoint, data somevalue)
{
if (output < (matrix + ROWS*COLS))
*(output++) = somevalue;
return output;
}
Now you can just say:
add_next(matrix, 42);
add_next(matrix, 9);
NOTE the output iterator thing assumes contiguous storage and therefore cannot be used with so-called jagged arrays
HTH
You can use memset to initialise arrays to a fixed value - it's a bit more efficient and cleaner looking than iterating over the array.
Checking for your 'empty' value can't be done much faster than you are doing it, though. :)
This sounds like you should think about your datatype. Since you are already using structs. why don't you add another int for the last unassigned value so you just loop to it. something like
e.g:
struct t_EmployeeKilos{
int kilos[maxtrips];
int nlast;
} EmployeeKilos[N];
and set nlast whenever you assign a new element in kilos. This way it is O(1).
for(int x=0;x<ctr-1;x++) //
{
if(employeenames[x].EmployeeNumber == log.Record)
{
EmployeeKilos[x].kilos[EmployeeKilos[x].nlast] = log.Kilometers;
EmployeeKilos[x].nlast++;
}
}