dragoljub
dragoljub

Reputation: 19

Returning to the start of a for loop in C

Even though this question has been asked a million times I just haven't found an answer that actually helps my case, or I simply can't see the solution.

I've been given the task to make a program that takes in a whole number and counts how many times each digit appears in it and also not showing the same information twice. Since we're working with arrays currently I had to do it with arrays of course so since my code is messy due to my lack of knowledge in C I'll try to explain my thought process along with giving you the code.

After entering a number, I took each digit by dividing the number by 10 and putting those digits into an array, then (since the array is reversed) I reversed the reverse array to get it to look nicer (even though it isn't required). After that, I have a bunch of disgusting for loops in which I try to loop through the whole array while comparing the first element to all the elements again, so for each element of the array, I compare it to each element of the array again. I also add the checked element to a new array after each check so I can primarily check if the element has been compared before so I don't have to do the whole thing again but that's where my problem is. I've tried a ton of manipulations with continue or goto but I just can't find the solution. So I just used **EDIT: return 0 ** to see if my idea was good in the first place and to me it seems that it is , I just lack the knowledge to go back to the top of the for loop. Help me please?

// With return 0 the program stops completely after trying to check the digit 1 since it's been checked already. I want it to continue checking the other ones but with many versions of putting continue, it just didn't do the job. //

/// Tried to make the code look better. ///

#include <stdio.h>


#define MAX 100

int main()
{
int a[MAX];
int b[MAX];
int c[MAX];
int n;
int i;
int j;
int k;
int counter1;
int counter2;


printf("Enter a whole number: ");
scanf("%i",&n);
while (1)
{
    for (i=0,counter1=0;n>10;i++) 
    {
        a[i] = n%10;
        n=n/10;
        counter1+=1;
        if (n<10)
        a[counter1] = n;
    }
    break;      
}


printf("\nNumber o elements in the array: %i", counter1);
printf("\nElements of the array a:");
for (i=0;i<=counter1;i++)
{
    printf("%i ",a[i]);
}


printf("\nElements of the array b:");
for (i=counter1,j=0;i>=0;i--,j++) 
{   
    b[j] = a[i];
}
for (i=0;i<=counter1;i++) 
{   
    printf("%i ",b[i]);
}

for (i=0;i<=counter1;i++)
{   
    for(k=0;k<=counter1;k++)
    {
        if(b[i]==c[k])
        {
        return 0;
        }
    }
    for(j=0,counter2=0; j<=counter1;j++)
    {
        if (b[j] == b[i])
        {
        counter2+=1;
        }
    }
    printf("\nThe number %i appears %i time(s)", b[i], counter2);
    c[i]=b[i];
}
} 

Upvotes: 1

Views: 1396

Answers (4)

Weather Vane
Weather Vane

Reputation: 34585

Here is another offering that uses only one loop to analyse the input. I made other changes which are commented.

#include <stdio.h>

int main(void)
{
    int count[10] = { 0 };
    int n;
    int digit;
    int elems = 0;
    int diff = 0;

    printf("Enter a whole number: ");
    if(scanf("%d", &n) != 1 || n < 0) {           // used %d, %i can accept octal input
        puts("Please enter a positive number");   // always check result of scanf 
        return 1;
    }

    do {
        elems++;                                  // number of digits entered
        digit = n % 10;
        if(count[digit] == 0) {                   // number of different digits
            diff++;
        }
        count[digit]++;                           // count occurrence of each
        n /= 10;
    } while(n);                                   // do-while ensures a lone 0 works

    printf("Number of digits entered: %d\n", elems);
    printf("Number of different digits: %d\n", diff);
    printf("Occurrence:\n");
    for(n = 0; n < 10; n++) {
        if(count[n]) {
            printf("    %d of %d\n", count[n], n);
        }
    }
    return 0;
} 

Program session:

Enter a whole number: 82773712
Number of digits entered: 8
Number of different digits: 5
Occurrence:
    1 of 1
    2 of 2
    1 of 3
    3 of 7
    1 of 8

Upvotes: 0

Niklas Rosencrantz
Niklas Rosencrantz

Reputation: 26652

Please try and see if this program can help you.

#include <stdio.h>

int main() {
    unsigned n;
    int arr[30];
    printf("Enter a whole number: ");
    scanf("%i", &n);
    int f = 0;
    while(n)
    {
        int b = n % 10;
        arr[f] = b;
        n /= 10;
        ++f;
    }
    for(int i=0;i<f;i++){
        int count=1;
        for(int j=i+1;j<=f-1;j++){
            if(arr[i]==arr[j] && arr[i]!='\0'){
                count++;
                arr[j]='\0';
            }
        }
        if(arr[i]!='\0'){
            printf("%d is %d times.\n",arr[i],count);
        }
    }
}

Test

Enter a whole number: 12234445
5 is 1 times.
4 is 3 times.
3 is 1 times.
2 is 2 times.
1 is 1 times.

Upvotes: 0

M Oehm
M Oehm

Reputation: 29116

The task at hand is very straightforward and certainly doesn't need convoluted constructions, let alone goto.

Your idea to place the digits in an array is good, but you increment counter too early. (Remember that arrays in C start with index 0.) So let's fix that:

int n = 1144526;        // example number, assumed to be positive

int digits[12];         // array of digits
int ndigit = 0;

while (n) {
    digits[ndigit++] = n % 10;
    n /= 10;
}

(The ++ after ndigit will increment ndigit after using its value. Using it as array index inside square brackets is very common in C.)

We just want to count the digits, so reversing the array really isn't necessary. Now we want to count all digits. We could do that by counting all digits when we see then for the first time, e.g. in 337223, count all 3s first, then all 7s and then all 2s, but that will get complicated quickly. It's much easier to count all 10 digits:

int i, d;

for (d = 0; d < 10; d++) {
    int count = 0;

    for (i = 0; i < ndigit; i++) {
        if (digit[i] == d) count++;
    }

    if (count) printf("%d occurs %d times.\n", d, count);
}

The outer loop goes over all ten digits. The inner loop counts all occurrences of d in the digit array. If the count is positive, write it out.

If you think about it, you can do better. The digits can only have values from 0 to 9. We can keep an array of counts for each digit and pass the digit array once, counting the digits as you go:

int count[10] = {0};

for (i = 0; i < ndigit; i++) {
    count[digit[i]]++;
}

for (i = 0; i < 10; i++) {
    if (count[i]) printf("%d occurs %d times.\n", i, count[i]);
}

(Remember that = {0} sets the first element of count explicitly to zero and the rest of the elements implicitly, so that you start off with an array of ten zeroes.)

If you think about it, you don't even need the array digit; you can count the digits right away:

int count[10] = {0};

while (n) {
    count[n % 10]++;
    n /= 10;
}

for (i = 0; i < 10; i++) {
    if (count[i]) printf("%d occurs %d times.\n", i, count[i]);
}

Lastly, a word of advice: If you find yourself reaching for exceptional tools to rescue complicated code for a simple task, take a step back and try to simplify the problem. I have the impression that you have added more complicated you even you don't really understand instead.

For example, your method to count the digits is very confused. For example, what is the array c for? You read from it before writing sensible values to it. Try to implement a very simple solution, don't try to be clever at first and go for a simple solution. Even if that's not what you as a human would do, remeber that computers are good at carrying out stupid tasks fast.

Upvotes: 1

paytonbissell
paytonbissell

Reputation: 16

I think what you need is a "continue" instead of a return 0.

for (i=0;i<=counter1;i++) {
  for(k=0;k<=counter1;k++) {
    if(b[i]==c[k]) {
      continue;   /* formerly return 0; */
    }

    for(j=0,counter2=0; j<=counter1;j++)
        if (b[j] == b[i]){
          counter2+=1;
        }
  }

Upvotes: 0

Related Questions