I'm currently working on a homework assignment and what I have to do is ask for the size of the array and what I would like to loop through it (how many things I should skip through). Example (I bolded what would be the users response)
How large is the array?
10
How would you like to iterate through it?
3
Conditions:
Then it should loop through every third item and then start over looping through the items that haven't been picked until the last one. I must also start on the first item (0) which you can see in my code that I provided.
This is what I thought I could do...
int amount=0, often=0, counter=0, x;
printf("Size of Array? ");
scanf("%d", &amount);
printf("iteration size? ");
scanf("%d", &often);
// sets the array (1 means it exists)
int[] array[amount];
for(x=0; x<amount; x++)
array[x] = 1;
// the part that I'm confused on
// supposed to iterate through everything
for(x=0; x<amount; x++){
if(array[0] == 1){
printf("#0\n");
array[0]=0;
}
if(array[x]==1)
counter++;
if(counter == often){
printf("#%d\n", x);
array[x]=0;
counter=0;
}
return 0;
}
However, I need to continuously loop through until the entire array is done except for the last one. Mine stops after I loop through the array once. This is the output I have verse the output I want.
My output:
0
3
6
9
Wanted output:
0
3
6
9
4
8
5
2
7
Notice how the the wanted output loops through it again picking the third number that hasn't been picked yet. That is where I'm confused and how to fix this problem. Any guidance or information would be great, thanks.
You need to keep looping until all numbers have been printed,
for instance like this:
int total = amount;
counter = often - 1;
while (total > 0) {
for(x=0; x<amount; x++){
if(array[x]==1)
counter++;
if(counter == often){
printf("#%d\n", x);
array[x]=0;
counter=0;
total--;
}
}
}
Edit: The entire program:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int amount=0, often=0, counter=0, x;
printf("Size of Array? ");
scanf("%d", &amount);
printf("iteration size? ");
scanf("%d", &often);
// sets the array (1 means it exists)
int array[amount]; // Fixed typo in declaration
for(x=0; x<amount; x++)
array[x] = 1;
// the part that I'm confused on
// supposed to iterate through everything
int total = amount;
counter = often - 1;
while (total > 0) {
for(x=0; x<amount; x++){
if(array[x]==1)
counter++;
if(counter == often){
printf("#%d\n", x);
array[x]=0;
counter=0;
total--;
}
}
}
return 0;
}
Compilation:
gcc -std=c99 -Wall a.c -o a
Running the program:
Size of Array? 10
iteration size? 3
#0
#3
#6
#9
#4
#8
#5
#2
#7
#1
Let's start out with a loop which skips every three numbers:
for(int i = 0; i < amount; i += 3)
{
print(i);
array[i] = 0;
}
Now, this only seems to work for 0, 3, 6, 9.
We want to be able to start at the first existing value, and repeat this process until nothing remains.
So let's put another loop on the outside, to count how many items remain:
int total = amount;
while(total > 0)
{
for(int i = 0; i < amount; i += 3)
{
print(i);
array[i] = 0;
total--;
}
}
Good so far, but we still start at 0 every time. We want to start at a particular value, and skip until the 3rd number is reached.
int total = amount;
while(total > 0)
{
for(int i = getStartingIndex(array, 3); i < amount; i += 3)
{
while(array[i] == 0 && i < amount)
i++;
print(i);
array[i] = 0;
total--;
}
}
Let's define our getStartingIndex function:
int getStartingIndex(int array[], int skipCount)
{
int index = 0;
for(int i = 0; i < skipCount; i++)
{
while(array[index] == 0)
index++;
index++;
}
return index - 1;
}
Now, we start at the value specified, and print numbers until we reach amount. And then we go back to the beginning, but we start at the third unused number.
We need to keep the current step size, it will run from zero to the desired step size and each time we visit an index and mark it as visited we will reset that counter to zero. Our main loop will iterate over the array one by one, until there are no unvisited indices left. We make sure the index does not run out of bounds of the array, so when index hits the length of the array, we reset it to zero.
If you don't want the last element to be printed, just change the while loop's conditional to while (visited_count < total_length - 1)
int main() {
int array[10] = { 0 };
int total_length = 10;
int visited_count = 0;
int index = 0;
int step_size = 3;
int current_step = 3;
while (visited_count != total_length) /* while there are unvisited elements */
{
if (!array[index] && current_step == step_size) /* array[index] has value zero, and we are at the desired step count, so print that element and mark it as visited */
{
array[index] = 1;
visited_count++;
printf("%d\n", index);
current_step = 0; /* resetting the step counter */
}
index++; /* this is how we iterate over the array, incrementing it at each iteration */
if (index == total_length) /* checking for out-of-bounds of the array, if we hit the total length, the index should be reset. */
{
index = 0;
}
if (!array[index]) /* now that we have stepped through the array, we increment the step counter if that element is not visited. */
{
current_step++;
}
}
return 0;
}
Related
So I have this problem I'm trying to solve for a couple of days now, and I just feel lost.
The function basically needs to get the size(n) of a sequence.
The user inputs the size, and then the function will ask him to put the numbers of the sequence one after the other.
Once he puts all the numbers, the function needs to return the sum of the longest sequence.
For example, n=8, and the user put [1,3,5,7,11,13,15,16].
The result will be 16 because [1,3,5,7] is the longest sequence.
If n=8 and the user put [1,3,5,7,11,15,19,20], the result will be 52, because although there are 2 sequences with the length of 4, the sum of [7,11,15,19] is bigger then [1,3,5,7].
The sequence doesn't necessarily needs to be increasing, it can be decreasing too.
The function can't be recursive, and arrays can't be used.
I hope it's clear enough what the problem is, and if not, please let me know so I'll try to explain better.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i, size, num, nextNum, diff, prevDiff, currSeqLength = 0, currSum, prevSum = 0;
printf("Please enter the arithmetic list size: ");
scanf_s("%d", &size);
for (i = 1; i <= size; i++)
{
printf("Please enter num: ");
scanf_s("%d", &num);
while (i == 1)
{
prevSum = num;
nextNum = num;
currSeqLength++;
break;
}
while (i == 2)
{
currSum = prevSum + num;
diff = num - nextNum;
nextNum = num;
currSeqLength++;
break;
}
while (i >= 3)
{
prevDiff = diff;
diff = num - nextNum;
nextNum = num;
if (prevDiff == diff)
{
currSum += num;
currSeqLength++;
break;
}
else
{
prevDiff = diff;
// diff now should be the latest num - previous one
}
}
}
}
This is basically what I've managed so far. I know some things here aren't working as intended, and I know the code is only half complete, but I've tried so many things and I can't seem to put my finger on what's the problem, and would really love some guidance, I'm really lost.
A few problems I encountered.
When I enter a loop in which the difference between the new number and the old one is different than the previous loops(for instance, [4,8,11]), I can't seem to manage to save the old number(in this case 8) to calculate the next difference(which is 3). Not to mention the first 2 while loops are probably not efficient and can be merged together.
P.S I know that the code is not a function, but I wrote it this way so I can keep track on each step, and once the code works as intended I convert it into a function.
I tried out your code, but as noted in the comments, needed to keep track at various stages in the sequence checks which sequence had the longest consistent difference value. With that I added in some additional arrays to perform that function. Following is a prototype of how that might be accomplished.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int len, diff, longest;
printf("Enter the size of your sequence: ");
scanf("%d", &len);
int num[len], seq[len], sum[len];
for (int i = 0; i < len; i++)
{
printf("Enter value #%d: ", i + 1);
scanf("%d", &num[i]);
seq[i] = 0; /* Initialize these arrays as the values are entered */
sum[i] = 0;
}
for (int i = 0; i < len - 1; i++)
{
seq[i] = 1; /* The sequence length will always start at "1" */
sum[i] = num[i];
diff = num[i + 1] - num[i];
for (int j = i; j < len - 1; j++)
{
if (diff == num[j + 1] - num[j])
{
sum[i] += num[j + 1]; /* Accumulate the sum for this sequence */
seq[i] += 1; /* Increment the sequence length for this sequence portion */
}
else
{
break;
}
}
}
longest = 0; /* Now, determine which point in the lise of numbers has the longest sequence and sum total */
for (int i = 1; i < len; i++)
{
if ((seq[i] > seq[longest]) || ((seq[i] == seq[longest]) && (sum[i] > sum[longest])))
{
longest = i;
}
}
printf("The sequence with the longest sequence and largest sum is: [%d ", num[longest]);
diff = num[longest + 1] - num[longest];
for (int i = longest + 1; i < len; i++)
{
if ((num[i] - num[i - 1]) == diff)
{
printf("%d ", num[i]);
}
else
{
break;
}
}
printf("]\n");
return 0;
}
Some points to note.
Additional arrays are defined to track sequence length and sequence summary values.
A brute force method is utilized reading through the entered value list starting with the first value to determine its longest sequence length and continuing on to the sequence starting with the second value in the list and continuing on through the list.
Once all possible starting points are evaluated for length and total, a check is then made for the starting point that has the longest sequence or the longest sequence and largest sum value.
Following is a some sample terminal output utilizing the list values in your initial query.
#Dev:~/C_Programs/Console/Longest/bin/Release$ ./Longest
Enter the size of your sequence: 8
Enter value #1: 1
Enter value #2: 3
Enter value #3: 5
Enter value #4: 7
Enter value #5: 11
Enter value #6: 13
Enter value #7: 15
Enter value #8: 16
The sequence with the longest sequence and largest sum is: [1 3 5 7 ]
#Dev:~/C_Programs/Console/Longest/bin/Release$ ./Longest
Enter the size of your sequence: 8
Enter value #1: 1
Enter value #2: 3
Enter value #3: 5
Enter value #4: 7
Enter value #5: 11
Enter value #6: 15
Enter value #7: 19
Enter value #8: 20
The sequence with the longest sequence and largest sum is: [7 11 15 19 ]
No doubt this code snippet could use some polish, but give it a try and see if it meets the spirit of your project.
I know code-only answers are frowned upon, but this is the simplest I can come up with and its logic seems easy to follow:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i, size;
int currNum, currDiff;
int prevNum = 0, prevDiff = 0;
int currSum = 0, currSeqLen = 0;
int bestSum = 0, bestSeqLen = 0;
printf("Please enter the arithmetic list size: ");
scanf_s("%d", &size);
for (i = 0; i < size; i++)
{
printf("Please enter num: ");
scanf_s("%d", &currNum);
if (currSeqLen > 0)
{
currDiff = currNum - prevNum;
if (currSeqLen > 1 && currDiff != prevDiff)
{
/* New arithmetic sequence. */
currSeqLen = 1;
currSum = prevNum;
}
prevDiff = currDiff;
}
currSum += currNum;
prevNum = currNum;
currSeqLen++;
if (currSeqLen > bestSeqLen ||
currSeqLen == bestSeqLen && currSum > bestSum)
{
/* This is the best sequence so far. */
bestSeqLen = currSeqLen;
bestSum = currSum;
}
}
printf("\nbest sequence length=%d, sum=%d\n", bestSeqLen, bestSum);
return 0;
}
I have omitted error checking for the scanf_s calls. They can be changed to scanf for non-Windows platforms.
Consider we have to choose a Leader from n people. For this purpose, we create an
array of size n. We assign every candidate a number (1, 2, 3, 4, 5,….,n) and store it in array in
ascending order. We apply dancing chair (People struggle to get the chair!!! After stopping the
music, in each iteration one chair and one man is eliminated. The Final remaining one is the
winner) method. Suppose we start from index 0 then we have to skip 3 indexes and we will reach
at index 3. Set its value to zero and start again from index 4 and skip 3 indexes and we will reach at index 7. Repeat the same step and so on.
(1) When we reach at last index we will proceed to index 0 again (for example the last index is 19, we start the count from index 18 and skip 3 indexes then we will reach at 1 and set it to zero).
(2) If the reached element value is already 0 than set the next element to zero. Do the same process till only one element remaining?
We implement it by using array and function. Write a function SelectLeader () which takes array
as input and return the Leader.
#include <stdio.h>
int SelectLeader() {
int n, i;
int leader = 0;
printf("Enter total number of people to choose a Leader from: ");
scanf("%d", &n);
int array[n];
for (i = 0; i < n; i++) {
array[i] = i + 1;
}
for (i = 0; i <= n; i = (i + 3) % n) {
if (array[i] == 0) {
array[(i + 1) % n] = 0;
} else
array[i] = 0;
}
for (i = 0; i < n; i++) {
if (array[i] != 0) {
leader = i;
}
}
return leader;
}
int main() {
int L;
L = SelectLeader();
printf("Leader is the candidate with the index number %d\n", L);
}
You can use the following pesudo code
Suppose n= 10 , for easy understanding
I am creating a boolean flag array to check whether number is selected or not.
jump = 3
i = 0
for (int cnt=0;cnt<10;) {
if(flag[i%10] === false) {
flag[i%10]=true;
cnt+=1;
i+=jump;
}
else {
i+=1;
}
}
The index element remaining with flag false is ans.
However this approach is both space and time expensive.
So I have to write some code that reads from a file and outputs certain parts of it.
For one part of it, I have to read some values and print out the one that occurs the most.
My problem is that if there are more than 1 values that occur a maximum amount of times (e.g. 5 and 4 both occur 2 times), my code is printing the latter value.
I want to print the first one (in this example, that would be 5). How do I do that?
Here is my code so far;
int find_max(int id[], char poi_names[][51], int num){
int max_index = 0;
int max_freq = 1;
for(int i = 0; i < num -1; i++){
int freq = 1;
for(int j = 0; j < num; j++){
if(id[i] == id[j]){
freq ++;
}
}
if(max_freq<freq){
max_index = i;
max_freq = freq;
}
}
return max_index;
}
Insert another condition if frequency is same as max frequency and in that condition check if the max_index is less than the index, if less than print.
else if (max_freq == freq){
if(max_index > index)
max_index = index
}
I think this should give the first occurrence.
Instead of checking for (max_freq lessthan freq), allow it to replace the id also when (max_freq==freq)... This will allow new values with the same freq to replace the previous maximum.
if(max_freq<=freq){
max_index = i;
max_freq = freq;
}
try to input 20 numbers with array and to output
the numbers in the double location only but somehow it's print
also the 0 location... please help.
#include<stdio.h>
#define n 20
int main()
{
int num[n]={0},i=0,order=1,double_locaion=0;
for(i=0;i<n;i++)
{
printf("please enter %d number\n",order);
scanf("%d",&num[i]);
order++;
}
for(i=0;i<n;i++)
{
if (i%2==0 && i!=1 && i!=0)
{
printf("%d\n",num[i]);
}
}
}
Try this, start with 2 and increase by 2 every time, the you don't have to deal with 0th element and odd element.
for (i = 2; i < n; i += 2)
{
printf("%d\n",num[i]);
}
First of all there is no way that your code is printing the 0-th location of the array. That's impossible given the condition of the if statement.
Secondly n- you don;t need to use macro expansion for that name.
/* This program takes 20 integer number from input.
* Prints the numbers entered in odd positions.(First,Third,..etc).
*/
#include<stdio.h>
#include<stdlib.h>
#define NUM 20
int main(void)
{
int numArr[NUM];
for(size_t i = 0; i < NUM; i++) {
printf("please enter %zu number\n",i+1);
if( scanf("%d",&numArr[i]) != 1){
fprintf(stderr, "%s\n","Error in input" );
exit(1);
}
}
for(size_t i = 0; i < n; i++)
{
if( i%2 == 0 )// if you want to omit the first number put the
// the condition (i%2 == 0 && i)
{
printf("%d\n",numArr[i]);
}
}
return 0;
}
What you did wrong that your code skipped 0th element?
if (i%2==0 && i!=1 && i!=0)
^^^^
i when 0 makes this condition false - and you never get to print it.
i!=1 ?
If i=1 then i%2 will be 1, so you will not even check the second conditions, the whole conditional expression will become false. So you can safely omit this logic.
Is there a better way?
Sure,
for(size_t i = 0; i < n; i += 2){
printf("%d\n",num[i]);
}
Explanation
If you consider that every time you check the modular arithmetic of 2 the elements which results to 0 remained are
0,2,4,6,8,10,...18
See the pattern? Starts with 0 and increments by 2 each time and when does it stop? Yes before reaching 20 coding it we get
for(size_t i = 0; i < n; i += 2){
/* Initialize with i=0 as first number is 0 (i=0)
* Increments by 2 (i+=2)
* Runs when less than 20 (i<n)
*/
printf("%d\n",num[i]);
}
If you want to omit the 0-th index do initialize properly
for(size_t i = 2; i < n; i += 2){
If you mean you want the numbers from array that are present at even position than you can do like this:
for (i = 2; i < n; i=i + 2) //Initialize i = 0 if 0 is consider as even
{
printf("%d\n",arr[i]);
}
I above code i is initialized to 2 and the increment in each iteration is 2 so it will access elements only at even position (2,4,6...).
My objective for this program is to let the user determine the size of the array and dynamically allocate memory for whatever size they choose. Once the user defines the size of the array, random numbers that do no exceed the size of the array are placed into all of the allotted positions. Where I am having issues is removing duplicates from the array and replacing them with a value that is not being used,
Example:
Please enter the size of the array:
User Input: 5
Output of code: 5, 3, 3, 1, 2
I would need it to be something like this:
Please enter the size of the array:
User Input: 3
Output of program: 3, 1, 2
Currently reading "C Programming - A Modern Approach" by K.N. King (Second Edition).
if someone could point me in the right direction on how to approach this, it would be much appreciated.Here is my code thus far.
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0
typedef int bool;
int main() {
int *UserData;
int TempPost;
int replace;
int UserInput;
int i;
int result;
bool digit_seen[UserInput];
int digit;
srand ((unsigned) time(NULL));
printf("Please enter the size of the array using a whole number: \n");
scanf("%d", &UserInput);
UserData = malloc(sizeof(int) * (UserInput ) +1);
for(i=0; i < UserInput; i ++) {
result = (( rand() % UserInput) + 1);
}
// check for duplicate values while putting values in array
while(UserInput>0){
digit = UserInput % UserInput;
if(digit_seen[digit])
break;
digit_seen[digit] = true;
UserInput /= UserInput;
if(UserInput > 0)
printf("Repeated digit \n");
else
printf("No repeated digit \n");
}
// Sorting the array using a Bubble sort
while(1){
replace = 0;
for (i=0; i<(UserInput - 1); i++){
if(UserData[i]>UserData[i+1]){
TempPost = UserData[i];
UserData[i] = UserData[i+1];
UserData[i+1] = TempPost;
replace = 1;
}
}
if(replace==0){
break;
}
}
printf("%d \n", result);
return 0;
}
It's not the most efficient way, but you can do it as you're generating the random numbers. When you pick a random number, go through all the previous elements of the array and see if it's already been used. Keep looping until you pick an unused number.
for (i = 0; i < UserInput; i++) {
do {
result = ( rand() % UserInput) + 1;
} while (in_array(result, UserData, i-1));
UserData[i] = result;
}
int in_array(int val, int* array, int array_size) {
for (int i = 0; i < array_size; i++) {
if (array[i] == val) {
return 1;
}
}
return 0;
}
A slightly more efficient way to do it is to initialize the array to 0. Then instead of picking random numbers, pick a random index to fill in, and repeat this until you pick an index that contains 0.
UserData = calloc(UserInput, sizeof(int));
for (i = 1; i <= UserInput; i++) {
int index;
do {
index = rand() % UserInput;
} while (UserData[index] != 0)
UserData[index] = i;
}
What you can do is shuffle the array instead. Just fill the array with all the numbers in order using a simple for loop, then shuffle it with something like this:
//read user input
//create array and fill with all the numbers in order
//[0,1,2,3,4,5 .. ... ]
int index, temp;
// size is the size of the array
for(int i = 0; i < size; i++)
{
index = rand()%size;//random place to pick from
temp = array[i];
array[i] = array[index];
array[index] = temp;
}
This is a lot more effecient -and less error prone- than your current approach.