Using arrays in C - c

I have a troubling homework assignment and would like pointers in the correct direction.
The task is to develop a C program that accomplishes the following:
In the main(), create an a 2D array named qqqqq that can hold 48 integers (6 rows, 8 columns)
Populate qqqqq with randomly generated integer values between 1 and 15.
Calculate the total for each row.
Calculate the total for each column.
Display the contents of the 2D array in tabular format with the row totals to the right of the rows and the column totals at the bottom of the columns.
Where to start after main?
Here is what I have so far:
int main (void)
{
int qqqqq [6] [8];
int r;
int c;
srandom ((unsiged) time (NULL));
for (r=0; r <=6; r++)
{
for(c=0; c <=8; c++)
{
qqqqq[r][c] = random ( )
What do I do next?
I appreciate any help or guidance.
Thanks
-James

Algorithmic Thinking
Here is how I would tackle this problem:
Write the algorithm in my own words.
Find out how to generate random numbers in the C language.
Learn how to print information on the screen.
Algorithm
The algorithm is the set of steps you need to solve the problem. The task at hand already describes the problem, but it is often good practice to re-write it in your own words. (As a practical point, you can then take your words to your client -- in this case, your teacher -- and confirm that your understanding of the problem is correct.)
Create a 2D array
Populate the array with random numbers.
Calculate the sum of each row of numbers (need a row sum counter).
Calculate the sum of each column of numbers (need a column sum counter).
Print the 2D array to the screen.
Print the sum of each row at the end of each row.
Print the sum of each column at the end of each column.
Assumption: Neither sum of sums are printed. (For example, the sum of the column sum.)
Generate Random Numbers
Google is helpful here. Try a Google search for:
generate random integers C
You will find lots of help, especially tips about the rand() function. Modify the Google search:
generate random integers C rand()
This search finds a great resource: http://www.cplusplus.com/reference/clibrary/cstdlib/rand/
Print Information
Again, a Google search can help here:
print information on the screen in C
This yields: http://www.daniweb.com/software-development/c/threads/9688
The printf function seems handy. Find out more about it:
printf C
This yields a familiar site: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Development
If you really want to "wow" your professor:
Identify the parts of your program that are most likely to change and make them constants.
Separate your program into logical areas (called functions).
Use meaningful variable names. Yes r and c likely represent rows and columns, but for the amount of time it takes to spell out row and column, it will save anyone reading your code from having to either make a guess or read the code to discover its true use.
Tell your professor that qqqqq could use a better name. Suggest one, even.
For example:
#include <stdio.h>
/* Subject to change; only change it in one spot. */
#define MAX_ROWS 6
#define MAX_COLS 8
#define MIN_RANDOM_NUMBER 1
#define MAX_RANDOM_NUMBER 15
/** Returns a number between MIN_RANDOM_NUMBER and MAX_RANDOM_NUMBER. */
int randomNumber() {
return 0; /* FIX ME to use rand() and the modulus operator. */
}
int main( int argc, char *argv[] ) {
int qqqqq[MAX_ROWS][MAX_COLS];
/* FIX ME: Move these variables into the display function. */
int sumRows = 0;
int sumCols = 0;
/* Use different random numbers each time the program runs. */
seedRandomNumber();
/* Initialize the array with random numbers. */
for( int row = 0; row < MAX_ROWS; row++ ) {
for( int col = 0; col < MAX_COLS; col++ ) {
qqqqq[row][col] = randomNumber();
}
}
/* Display the array to the screen along with the sum totals. */
display( qqqqq );
}
Note that you have a choice to make.
You could pass the sumRows variable into the display function, or you could code the display function to call calculateSumRows itself. My preference is to always simplify the function prototypes. That is, reduce the number of parameters. It makes things easier to change in the future.
So write display as something like:
void display( int randomValues[MAX_ROWS][MAX_COLS] ) {
int sumCols = 0;
for( int row = 0; row < MAX_ROWS; row++ ) {
/* FIX ME: Write the calculateSumCols function. */
sumCols = calculateSumCols( randomValues, row );
for( int col = 0; col < MAX_COLS; col++ ) {
/* FIX ME: Use printf here to display the value at this row/column. */
}
}
/* FIX ME: Use printf here to display sumRows. */
for( int col = 0; col < MAX_COLS; col++ ) {
/* FIX ME: Use printf here to display the value of the rows. */
printf( "%d ", calculateSumRows( randomValues, col ) );
}
}
That should get you started.
Note that there are a number of simplifications and optimizations you could make here. Forget them. Get the code so that it actually works first. Once the code works, save it. Make a back up copy, even.
Then start to change it. See if you can remove variables. Perhaps you can even remove some of the for loops. If you make a mistake, you can always reference your back up copy. Eventually your "back up" copy will become a "source code repository".

That's a pretty good start! Note, though, that the valid indices for an arrayof dimension X are 0...(X-1). Your loops should look like
for (r=0; r <6; r++)
(Note that "<6" rather than "<=6".
Now you need another array to hold the row totals, and an array to hold the column totals, and then some more loops to calculate those and store them in the arrays.

Some key things:
What does random() return?
What is the total of a row/column?
This is just adding up all the
numbers in the row/column. Try
writing a function to add up all the
values in one given row or column.
Think of how to print out a row
of a matrix. Then do this for every
row in the matrix.

There are 6 rows and 8 columns, and you need a total for each of those. Start by making some more arrays as places to store those totals.

Related

Cycling through interval in C efficiently

I have dynamically allocated array consisting of a lot of numbers (200 000+) and I have to find out, if (and how many) these numbers are contained in given interval. There can be duplicates and all the numbers are in random order.
Example of numbers I get at the beginning:
{1,2,3,1484984,48941651,489416,1816,168189161,6484,8169181,9681916,121,231,684979,795641,231484891,...}
Given interval:
<2;150000>
I created a simple algorithm with 2 for loops cycling through all numbers:
for( int j = 0; j <= numberOfRepeats; j++){
for( int i = 0; i < arraySize; i++){
if(currentNumber == array[i]){
counter++;
}
}
currentNumber++;
}
printf(" -> %d\n", counter);
}
This algorithm is too slow for my task. Is there more efficient way for me to implement my solution? Could sorting the arrays by value help in this case / wouldn't that be too slow?
Example of working program:
{ 1, 7, 22, 4, 7, 5, 11, 9, 1 }
<4;7>
-> 4
The problem was simple as the single comment in my question answered it - there was no reason for second loop. Single loop could do it alone.
My changed code:
for(int i = 0; i <= arraySize-1; i++){
if(array[i] <= endOfInterval && array[i] >= startOfInterval){
counter++;
}
This algorithm is too slow for my task. Is there more efficient way for me to implement my solution? Could sorting the arrays by value help in this case / wouldn't that be too slow?
Of course, it is slow. A single pass algorithm to count the number of elements that are in the set should suffice, just count them in a single pass if they pass the test (be n[i] >= lower bound && be n[i] < upper bound or similar approach) will do the work.
Only in case you need to consider duplicates (e.g. not counting them) you will need to consider if you have already touched them or no. In that case, the sorting solution will be faster (a qsort(3) call is O(nlog(n)) against the O(nn) your double loop is doing, so it will run in an almost linear, then you make a second pass over the data (converting your complexity to O(nlog(n) + n), still lower than O(nn) for the large amount of data you have.
Sorting has the advantage that puts all the repeated key values together, so you have to consider only if the last element you read was the same as the one you are processing now, if it is different, then count it only if it is in the specified range.
One final note: Reading a set of 200,000 integers into an array to filter them, based on some criteria is normally a bad, non-scalable way to solve a problem. Your problem (select the elements that belong to a given interval) allow you for a scalable and better solution by streaming the problem (you read a number, check if it is in the interval, then output it, or count it, or whatever you like to do on it), without using a large amount of memory to hold them all before starting. That is far better way to solve a problem, as it allows you to read a true unbounded set of numbers (coming e.g. from a file) and producing an output based on that:
#include <stdio.h>
#define A (2)
#define B (150000)
int main()
{
int the_number;
size_t count = 0;
int res;
while ((res = scanf("%d", &the_number)) > 0) {
if (the_number >= A && the_number <= B)
count++;
}
printf("%zd numbers fitted in the range\n", count);
}
on this example you can give the program 1.0E26 numbers (assuming that you have an input file system large enough to hold a file this size) and your program will be able to handle it (you cannot create an array with capacity to hold 10^26 values)

Making a character array rotate its cells left/right n times

I'm totally new here but I heard a lot about this site and now that I've been accepted for a 7 months software development 'bootcamp' I'm sharpening my C knowledge for an upcoming test.
I've been assigned a question on a test that I've passed already, but I did not finish that question and it bothers me quite a lot.
The question was a task to write a program in C that moves a character (char) array's cells by 1 to the left (it doesn't quite matter in which direction for me, but the question specified left). And I also took upon myself NOT to use a temporary array/stack or any other structure to hold the entire array data during execution.
So a 'string' or array of chars containing '0' '1' '2' 'A' 'B' 'C' will become
'1' '2' 'A' 'B' 'C' '0' after using the function once.
Writing this was no problem, I believe I ended up with something similar to:
void ArrayCharMoveLeft(char arr[], int arrsize, int times) {
int i;
for (i = 0; i <= arrsize ; i++) {
ArraySwap2CellsChar(arr, i, i+1);
}
}
As you can see the function is somewhat modular since it allows to input how many times the cells need to move or shift to the left. I did not implement it, but that was the idea.
As far as I know there are 3 ways to make this:
Loop ArrayCharMoveLeft times times. This feels instinctively inefficient.
Use recursion in ArrayCharMoveLeft. This should resemble the first solution, but I'm not 100% sure on how to implement this.
This is the way I'm trying to figure out: No loop within loop, no recursion, no temporary array, the program will know how to move the cells x times to the left/right without any issues.
The problem is that after swapping say N times of cells in the array, the remaining array size - times are sometimes not organized. For example:
Using ArrayCharMoveLeft with 3 as times with our given array mentioned above will yield
ABC021 instead of the expected value of ABC012.
I've run the following function for this:
int i;
char* lastcell;
if (!(times % arrsize))
{
printf("Nothing to move!\n");
return;
}
times = times % arrsize;
// Input checking. in case user inputs multiples of the array size, auto reduce to array size reminder
for (i = 0; i < arrsize-times; i++) {
printf("I = %d ", i);
PrintArray(arr, arrsize);
ArraySwap2CellsChar(arr, i, i+times);
}
As you can see the for runs from 0 to array size - times. If this function is used, say with an array containing 14 chars. Then using times = 5 will make the for run from 0 to 9, so cells 10 - 14 are NOT in order (but the rest are).
The worst thing about this is that the remaining cells always maintain the sequence, but at different position. Meaning instead of 0123 they could be 3012 or 2301... etc.
I've run different arrays on different times values and didn't find a particular pattern such as "if remaining cells = 3 then use ArrayCharMoveLeft on remaining cells with times = 1).
It always seem to be 1 out of 2 options: the remaining cells are in order, or shifted with different values. It seems to be something similar to this:
times shift+direction to allign
1 0
2 0
3 0
4 1R
5 3R
6 5R
7 3R
8 1R
the numbers change with different times and arrays. Anyone got an idea for this?
even if you use recursion or loops within loops, I'd like to hear a possible solution. Only firm rule for this is not to use a temporary array.
Thanks in advance!
If irrespective of efficiency or simplicity for the purpose of studying you want to use only exchanges of two array elements with ArraySwap2CellsChar, you can keep your loop with some adjustment. As you noted, the given for (i = 0; i < arrsize-times; i++) loop leaves the last times elements out of place. In order to correctly place all elements, the loop condition has to be i < arrsize-1 (one less suffices because if every element but the last is correct, the last one must be right, too). Of course when i runs nearly up to arrsize, i+times can't be kept as the other swap index; instead, the correct index j of the element which is to be put at index i has to be computed. This computation turns out somewhat tricky, due to the element having been swapped already from its original place. Here's a modified variant of your loop:
for (i = 0; i < arrsize-1; i++)
{
printf("i = %d ", i);
int j = i+times;
while (arrsize <= j) j %= arrsize, j += (i-j+times-1)/times*times;
printf("j = %d ", j);
PrintArray(arr, arrsize);
ArraySwap2CellsChar(arr, i, j);
}
Use standard library functions memcpy, memmove, etc as they are very optimized for your platform.
Use the correct type for sizes - size_t not int
char *ArrayCharMoveLeft(char *arr, const size_t arrsize, size_t ntimes)
{
ntimes %= arrsize;
if(ntimes)
{
char temp[ntimes];
memcpy(temp, arr, ntimes);
memmove(arr, arr + ntimes, arrsize - ntimes);
memcpy(arr + arrsize - ntimes, temp, ntimes);
}
return arr;
}
But you want it without the temporary array (more memory efficient, very bad performance-wise):
char *ArrayCharMoveLeft(char *arr, size_t arrsize, size_t ntimes)
{
ntimes %= arrsize;
while(ntimes--)
{
char temp = arr[0];
memmove(arr, arr + 1, arrsize - 1);
arr[arrsize -1] = temp;
}
return arr;
}
https://godbolt.org/z/od68dKTWq
https://godbolt.org/z/noah9zdYY
Disclaimer: I'm not sure if it's common to share a full working code here or not, since this is literally my first question asked here, so I'll refrain from doing so assuming the idea is answering specific questions, and not providing an example solution for grabs (which might defeat the purpose of studying and exploring C). This argument is backed by the fact that this specific task is derived from a programing test used by a programing course and it's purpose is to filter out applicants who aren't fit for intense 7 months training in software development. If you still wish to see my code, message me privately.
So, with a great amount of help from #Armali I'm happy to announce the question is answered! Together we came up with a function that takes an array of characters in C (string), and without using any previously written libraries (such as strings.h), or even a temporary array, it rotates all the cells in the array N times to the left.
Example: using ArrayCharMoveLeft() on the following array with N = 5:
Original array: 0123456789ABCDEF
Updated array: 56789ABCDEF01234
As you can see the first cell (0) is now the sixth cell (5), the 2nd cell is the 7th cell and so on. So each cell was moved to the left 5 times. The first 5 cells 'overflow' to the end of the array and now appear as the Last 5 cells, while maintaining their order.
The function works with various array lengths and N values.
This is not any sort of achievement, but rather an attempt to execute the task with as little variables as possible (only 4 ints, besides the char array, also counting the sub function used to swap the cells).
It was achieved using a nested loop so by no means its efficient runtime-wise, just memory wise, while still being self-coded functions, with no external libraries used (except stdio.h).
Refer to Armali's posted solution, it should get you the answer for this question.

Generate random numbers without repeats

I want to generate random numbers without repeats till all gone, then again generating random numbers with the initial dataset.
I know keeping already generated numbers in an array and loopin through them to check whether it is alredy generated or the method deducting the numbers that are generated from the array and randomize numbers with the new array.
What I want is not those methods, if there is a way that is efficient using data structures will be quite nice, if it is any other method also ok
Thanks
Say you want to generate 1,000 unique random numbers and present them to some code one at a time. When you exhaust those numbers, you want to present the same numbers again, but in a different sequence.
To generate the numbers, use a hash table. In C#, it would look like this:
const int MaxNumbers = 1000;
HashSet<int> uniqueNumbers = new HashSet<int>();
Random rnd = new Random();
// generate random numbers until there are 1000 in the hash table
while (uniqueNumbers.Count < MaxNumbers)
{
uniqueNumbers.Add(rnd.Next());
}
// At this point you have 1,000 unique random numbers
// Put them in an array
int[] myNumbers = uniqueNumbers.ToArray();
This works because the HashSet.Add method rejects duplicates. And it's very fast because lookup in the hash table is O(1).
Now, you can serve them by setting a current index at 0 and increment it every time a number is requested. Something like:
int ixCurrent = 0;
int GetNextNumber()
{
if (ixCurrent < MaxNumbers)
{
++ixCurrent;
return myNumbers[ixCurrent-1];
}
But what to do when ixCurrent runs off the end of the array? Enter the Fisher-Yates Shuffle:
// out of numbers. Shuffle the array and return the first one.
for (int i = MaxNumbers-1; i > 0; --i)
{
int j = rnd.Next(i+1);
int temp = myNumbers[i];
myNumbers[i] = myNumbers[j];
myNumbers[j] = temp;
}
ixCurrent = 1;
return myNumbers[0];
}
If you know that the numbers you want to return are within a particular range (that is, you want to return the numbers 0-999 in random order), then you just fill an array with the values 0-999 and shuffle it.
I'm not sure what language you are using, but here's some C++ code that does what you're looking for. Instead of it searching an array, it just does a direct check of a specific section of memory for a set flag and if it isn't set then the number chosen is new and printed.
The section I marked as handler is the code that is first executed when a unique number is found. Change the 10's and the 11 to different numbers if you want a larger set of random numbers but you might have to wait forever for the output.
int main(int argc, char *argv[]){
char randn[10];
char randnset[10];
int n;
int ct=0;
memset(randnset,'1',10);
memset(randn,0,10);
while (ct < 10){
srand(time(NULL));
n=rand() % 11;
if (!randn[n]){
printf("%d\n",n); // handler
randn[n]='1';
ct++;
}
}
return 0;
}
Every random generator function takes a seed value as a parameter and uses it in its internal algorithm to generate random numbers. If you want to generate the same sequence of numbers, you have to use the same seed value. As an example you can achieve this in Java like this:
int seed = 10;
Random r = new Random(seed);
for(int i=0; i<10; i++){
System.out.println(r.nextInt());
}
The output is something like this (of course it will have different results in your system):
-1157793070
1913984760
1107254586
1773446580
254270492
-1408064384
1048475594
1581279777
-778209333
1532292428
and it gives me the same results each time I execute it.

Delete a column from a double array

I'm stuck here. I've got a matrix of size NxN stored in a double array. Then I want to delete a given column, lets say the first column. So I created a new double array of size NxN-1 and copy the values from the first matrix to the second one, except the 1st column of course. But then I want to set the first array to be the second array. I am blanking here.
double matrix[N][N]
//fill up the matrix code here...
// remove first column of array
double newMatrix[N][N-1];
for(i = 0; i < N; i++){
for(j = 1; j < N; j++){
newMatrix[i][j-1] = matrix[i][j];
}
}
matrix = newMatrix; // how do I set this correctly? Do I need to realloc the first array?
You cannot assign arrays in C, which I assume that your compiler tells you. To do such dynamic memory management, you will need to use pointers instead of arrays. I suggest you read up on how malloc() and free() work so that you can do what you want.
Edit:
Another solution comes to mind if you are only removing columns (or rows): keep track of the number of rows and columns used in the array. Then you can remove a row or column within the original array without creating a copy first. Just move the data past the delete column (or row) to the left (or up) then decrement your size counters. (I hope this make sense. If not let me know and I'll elaborate.)
like Code-guru said malloc() and free() should help alot, but if u simply wanted to delete the last column the you wouldn't need two arrays:
double matrix[2][3] = {1,2,3,4,5,6}; //declaring a 2 by 3 matrix
for (i=0;i<2;i++) //rows
{
for (j=0;j<3-1;j++) //columns - 1
{
printf("%.1f ",matrix[i][j]); //I chose to display matrix...
}
printf("\n");
}
Instead of accessing elements from array[i][j], one might opt to access elements from array + stride_x[x] + stride_y[y]; where array is originally introduced as double matrix[N*N]; or double *matrix = malloc(sizeof(double)*N*N);.
The stride_y[x] would originally contain offsets of columns for all rows: 0 1 2 3 4 ... N-1 and stride_y[y] would contain similar offsets multiplied with original row width 0 N 2*N 3*N..
From these 1-D arrays one can more effortlessly delete or exchange complete rows and columns, which may come handy in eg. recursive implementation of determinant calculation / Gauss Jordan elimination.

How to find a certain number in an Array C Programming?

If I have an array and I need to display how many times the number '12' is created. I'm using a function to go about this. What resources should I look into to find how to exactly tease out this one number and display how many times it is in the array/list? Any help would be greatly appreciated.
You can do it by walking through the array, while keeping a tally.
The tally starts at 0, and every time you reach the number you want to track, add one to it. When you're done, the tally contains the number of times the number appeared.
Your function definition would probably look something like this:
int count_elements(int pElement, int pArray[], size_t pSize);
Simply create a counter variable, and examine each element in the array in a loop, incrementing the counter variable every time an element is equal to 12.
If you have a plain C-array, you have to iterate over all elements in a loop and count yourself with a variable.
int arr[20];
int twelves = 0;
int i;
/* fill here your array */
/* I assume your array is fully filled, otherwise change the sizeof to the real length */
for(i = 0; i < sizeof(arr)/sizeof(int);++i) {
if(arr[i] == 12) ++twelves;
}
After this, the variable twelves will contain the number of twelves in the array.

Resources