I'm facing a slight problem with one of my projects. I am supposed to write a c program to calculate each character present in the input/file. (It's supposed to be a basic program.) The constraints - I cannot use the math.h library to produce log functions and obtain an output in the format:
1
5 1 2 0 2 2 5 8 4 3 6 6 2 5 5 7 2 1 1 2
7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
The program is supposed to count the number of occurrences of each alphabetic letter (case insensitive) in the stdin input stream and display a histogram.
As you can see, the output is formatted vertically with each line printing the base 10 number of the position of the character.
Now, this might seem silly, but what I have so far is this:
#include <stdio.h>
#include <ctype.h>
/*
int logBase10 (int num) {
method to calculate the log base 10 of num
}
*/
int main (int argc, char * argv[]) {
char alpha;
int count = 0;
int ascii[128] = {0};
while ( (alpha = getchar()) != EOF) {
count++;
ascii[(int)alpha]++;
alpha = getchar();
}
printf("Char \t Count \n");
printf("------------------------\n");
for (int i = 0; i < 127; i++) {
if(ascii[i] > 0) {
printf("%c \t %d \n", i, ascii[i]);
}
}
}
Which produces an output like this:
Char Count
------------------------
5
93
, 6
- 2
. 3
; 2
C 2
I 6
N 1
T 1
W 2
a 26
b 5
c 8
d 13
e 55
f 11
g 7
h 28
i 32
k 3
l 26
m 17
n 31
o 27
p 12
q 1
r 26
s 22
t 42
u 11
v 8
w 8
y 13
z 1
First off, my program is printing unwanted ascii characters (, ; - etc) and I am working on changing the print function to be more vertical, but I cannot figure out the log method at all. I know log(10) is 1 because 10^1 is 1, but I am having trouble figuring out how to use this to create the method itself. Also, for the extra characters, I tried using:
if(ascii[i] > 65 || ascii[i] < 90 || ascii[i] >= 97 || ascii[i] <= 122 ) {
printf("%c \t %d \n", i, ascii[i]);
}
to no avail. Trying that produced more gibberish characters instead.
Any help/feedback is appreciated.
Soul
The commenters have already pointed out issues with your code. Here's a version that counts only letters and prints vertical labels. It doesn't need <ctype.h> or <math.h>.
Each character hets a letter index which is a number from 0 to 25 for upper and lower case letters and −1 if the character isn't a letter. That reduces the array size to 26.
You could find out each digit with elaborate calculations, but the easiest way is to print the number to a string. snprintf does this for you. You can right-align the number with a field width. The maximum value for a typical int is about 2 billion, which has 10 digits. You should account for that, even if you had to pass in the whole Moby-Dick plus the Bible to get that many counts.
You can test whether you should start printing by assuming a width of ten digits first and checking whether the maximum count has ten digits, that is whether it is 1,000,000,000 or higher. Then divide that limit by 10 in each iteration.
Here's the code:
#include <stdio.h>
// return letter index or -1 for non-letter
int letter(int c)
{
if ('a' <= c && c <= 'z') return c - 'a';
if ('A' <= c && c <= 'Z') return c - 'A';
return -1;
}
int main(int argc, char * argv[])
{
int count[26] = {0}; // letter counts
char label[26][12]; // buffer for printing numbers
int limit = 1000000000; // smallest 10-digit number
int max = 0;
int i, j;
// read and count letters
while (1) {
int c = getchar();
if (c == EOF) break;
c = letter(c);
if (c >= 0) count[c]++;
}
// write auxiliary labels
for (i = 0; i < 26; i++) {
snprintf(label[i], sizeof(label[i]), "%10d", count[i]);
if (count[i] > max) max = count[i];
}
// print vertical labels
for (j = 0; j < 10; j++) {
if (max >= limit) {
for (i = 0; i < 26; i++) {
putchar(' ');
putchar(label[i][j]);
}
putchar('\n');
}
limit /= 10;
}
// print horizontal rule
for (i = 0; i < 26; i++) {
putchar('-');
putchar('-');
}
putchar('-');
putchar('\n');
// print letters
for (i = 0; i < 26; i++) {
putchar(' ');
putchar('A' + i);
}
putchar('\n');
return 0;
}
On your example, it produces:
1
5 1 2 0 2 2 5 8 4 3 6 6 2 5 5 7 2 1 1 2
7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2
-----------------------------------------------------
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
One easy way to figure out how many digits that you'll need is to use sprintf to convert the integer count to a string, and then use strlen to find out how many digits you have. For example:
char str[20] = {0}; // 20 digits should be enough for your case
for (i = 0; i < 128; i++) {
sprintf(str, "%d", ascii[i]);
num_digits = strlen(str);
printf("%d has %d digits\n", ascii[i], num_digits);
}
I didn't test the code, but it should be close.
Some pseudo code
Find max count
Find width of that count when printed w=sprintf(buf, "%d", mxcnt)
Loop w times (wi = 0 to w - 1)
for each non-zero count
form string sprintf(buf, "%*d", w, count[i])
print buf[wi] character
print space
print \n
Related
How do I make my code have an output like this:
Enter your number: 4
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
I can't seem to figure out how to make it so the last digit prints the next value iteration.
#include <stdio.h>
int main(){
int num;
int i = 1;
printf("Enter your number: ");
scanf("%d", &num);
for(i = 1; i<=num; i++){
for(int j = 0; j<num; ++j)
{
printf("%d ",i);
}
printf("\n");
}
Doing this using nested loops are simple and doesn't require any kind of special calculations, if-statements or other more or less fancy stuff. Just keep it simple.
Your task is:
for each row:
print "rowindex+1 and a space" n-1 times
print "rowindex+2 and a newline" 1 time
"for each row" is one simple loop.
"n-1 times" is another (nested) simple loop.
So keep it simple... just two ordinary for-loops like:
#include <stdio.h>
int main()
{
int n = 4;
for (int i = 0; i < n; i++) // for each row
{
for (int j = 0; j < n-1; j++) // n-1 times
{
printf("%d ", i + 1);
}
printf("%d\n", i + 2); // 1 time
}
return 0;
}
Here is something kind of from out in the left field, and off topic, leaving behind not only the requirements of the homework, but the C language. However, we will find our way back.
We can solve this problem (sort of) using text processing at the Unix prompt:
We can treat the smallest square
12
23
as an initial seed kernel, which is fed through a little command pipeline to produce a square of the next size (up to a single digit limitation):
We define this function:
next()
{
sed -e 's/\(.\).$/\1&/' | awk '1; END { print $0 | "tr \"[1-9]\" \"[2-8]\"" }'
}
Then:
$ next
12
23
[Ctrl-D][Enter]
112
223
334
Now, copy the 3x3 square and paste it into next:
$ next
112
223
334
[Ctrl-D][Enter]
1112
2223
3334
4445
Now, several steps in one go, by piping through multiple instances of next:
$ next | next | next | next | next
12
23
[Ctrl-D][Enter]
1111112
2222223
3333334
4444445
5555556
6666667
7777778
The text processing rule is:
For each line of input, repeat the second-to-last character. E.g ABC becomes ABBC, or 1112 becomes 11112. This is easily done with sed.
Add a new line at the end which is a copy of the last line, with each digit replaced by its successor. E.g. if the last line is 3334, make it 4445. The tr utility helps here
To connect this to the homework problem: a C program could be written which works in a similar way, starting with an array which holds the 1 2 2 3 square, and grows it. The requirement for nested loops would be satisfied because there would be an outer loop iterating on the number of "next" operations, and then an inner loop performing the edits on the array: replicating the next-to-last column, and adding the new row at the bottom.
#include <stdio.h>
#include <stdlib.h>
#define DIM 25
int main(int argc, char **argv)
{
if (argc != 2) {
fputs("wrong usage\n", stderr);
return EXIT_FAILURE;
}
int n = atoi(argv[1]);
if (n <= 2 || n > DIM) {
fputs("invalid n\n", stderr);
return EXIT_FAILURE;
}
int array[DIM][DIM] = {
{ 1, 2 },
{ 2, 3 }
};
/* Grow square from size 2 to size n */
for (int s = 2; s < n; s++) {
for (int r = 0; r < s; r++) {
array[r][s] = array[r][s-1];
array[r][s-1] = array[r][s-2];
}
for (int c = 0; c <= s; c++) {
array[s][c] = array[s-1][c] + 1;
}
}
/* Dump it */
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++)
printf("%3d ", array[r][c]);
putchar('\n');
}
return 0;
}
#include<stdio.h>
int main(){
int n;
printf("Enter the number: ");
scanf("%d",&n);
for(int i =1; i<=n; i++){
for(int j=1;j<=n;j++) {
if(j==n)
printf("%d\t",i+1);
else
printf("%d\t",i);
}
printf("\n");
}
return 0;}
Nested loops will drive you crazy, trying figure out their boundaries.
While I usually oppose adding more variables, in this case it seems justified to keep track of things simply.
#include <stdio.h>
int main() {
int n = 4, val = 1, cnt1 = 1, cnt2 = 0;
for( int i = 1; i < n*n+1; i++ ) { // notice the 'square' calculation
printf( "%d ", val );
if( ++cnt1 == n ) // tired of this digit? start the next digit
cnt1 = 0, val++;
if( ++cnt2 == n ) // enough columns output? start the next line
cnt2 = 0, putchar( '\n' );
}
return 0;
}
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
A single example of desired output is hard to go by, especially when the code doesn't help... Anyway, here's the output when 'n' = 5.
1 1 1 1 2
2 2 2 2 3
3 3 3 3 4
4 4 4 4 5
5 5 5 5 6
All of these kinds of assignments are to try to get you to recognize a pattern.
The pattern you are given
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
is very close to
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
which is an easy nested loop. Write a solution to the easier pattern. Once you have that you can then you can fix it.
Hint: Notice that the only thing that changes is the last item of the inner loop.
Edit
This totally breaks the spirit of the assignment, and if you, dear student, ever try to submit something like this your professor will... probably not care, but also know full well that you didn’t do it. If I were your professor you’d lose marks, even if I knew you weren’t cheating and had written something this awesome yourself.
Single loop. Stuff added to pretty print numbers wider than one digit (except the very last). Maths, yo.
#include <stdio.h>
#include <math.h>
void print_off_by_one_square( int n )
{
int width = (int)log10( n ) + 1;
for (int k = 0; k++ < n*n ;)
printf( "%*d%c", width, (k+n)/n, (k%n) ? ' ' : '\n' );
}
int main(void)
{
int n;
printf( "n? " );
fflush( stdout );
if ((scanf( "%d", &n ) != 1) || (n < 0))
fprintf( stderr, "%s\n", "Not cool, man, not cool at all." );
else
print_off_by_one_square( n );
return 0;
}
The way it works is pretty simple, actually, but I’ll leave it as an exercise for the reader to figure out on his or her own.
Here is a different concept. Some of the answers are based on the idea that we first think about
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
and then tweak the logic for the item in the last line.
But we can regard it like this also:
We have a tape which goes like this:
1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4
and we are blindly cutting the tape into four-element pieces to form a 4x4 square. Suppose someone deletes the first item from the tape, and then adds 5:
1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5
Now, if we cut that tape blindly by the same process, we will get the required output:
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
Suppose we have a linear index through the tape, a position p starting at 0.
In the unshifted tape, item p is calculated using p / 4 + 1, right?
In the shifted tape, this is just (p + 1) / 4 + 1. Of course we substitute the square size for 4.
Thus:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc != 2) {
fputs("wrong usage\n", stderr);
return EXIT_FAILURE;
}
int n = atoi(argv[1]);
int m = n * n;
if (n <= 0) {
fputs("invalid n\n", stderr);
return EXIT_FAILURE;
}
for (int p = 0; p < m; p++) {
printf("%3d ", (p + 1) / n + 1);
if (p % n == n - 1)
putchar('\n');
}
return 0;
}
$ ./square 2
1 2
2 3
$ ./square 3
1 1 2
2 2 3
3 3 4
$ ./square 4
1 1 1 2
2 2 2 3
3 3 3 4
4 4 4 5
I'm having the following problem:
A park that have the form of a m x n board. There are k kinds of trees (1 <= k <= 100). The park is divided into m x n cells and each cell, they'll plant a tree. Now, on the map, each cell of the park have an integer i inside if the i-th kind of tree is planted in it, or a 0 if no tree is planted in it. A line of cells is considered "good" if it has at least t trees of same types, (and they must be on the same either line or column). Count the number of trees that is not in a "good" line.
Input: Integers m, n, t and an m x n array of integers represent the map.
Output: Number of trees that is not in a "good" line.
Example:
Input:
5 6 3
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
Output: 10
Explanation: The bold numbers are the trees that is not in a good line.
1 3 3 3 3 4
1 2 3 2 0 4
3 2 2 2 4 4
1 0 0 2 4 0
1 2 3 0 4 4
My idea is to check for each element in the array. If it is satisfied then I'll move to the nearest element outside the "good" line. Else, it will just move to the next element on the same line, or if the line is ended then the next element on the column.
Here is my code
#include <stdio.h>
#define maxn 120
int a[maxn][maxn], m, n, t;
int check(int *i, int *j){
int k, cnt_r, cnt_c;
cnt_r = 0;
//jump to the nearest cell that is not in good line
for(k = *i + 1; k < m; k++){
if(a[*i][*j] == a[k][*j]) cnt_r++;
if(cnt_r >= t){
*i = k;
return 1;
}
}
cnt_c = 0;
for(k = *j + 1; k < n; k++){
if(a[*i][*j] == a[*i][k]) cnt_c++;
if(cnt_c >= t){
*j = k;
return 1;
}
}
return 0;
}
//check if this is the last square or not
int lastSq(int r, int c){
return (r == n - 1 && c == n);
}
int main(){
int res = 0, i, j, pos_r = 0, pos_c = 0;
scanf("%d%d%d", &m, &n, &t);
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
scanf("%d", &a[i][j]);
while(!lastSq(pos_r, pos_c)){
if(a[pos_r][pos_c] == 0){
if(pos_c < n - 1) pos_c++;
else if(pos_r < n - 1){
pos_c = 0;
pos_r++;
}
}
if(!check(&pos_r, &pos_c)){
res++;
if(pos_c < n - 1) pos_c++;
else{
pos_c = 0;
pos_r++;
}
}
}
printf("%d", res);
}
But it doesn't print any output. The only thing I have is 0xC0000005. Can someone please check where did I make a mistake and provide me a direction? Thanks.
Program - Rotating matrix 90 degrees clockwise.
I am a beginner in coding. I came across this question on GeeksforGeeks. I found the solutions very complex so tried applying my logic. But I don't know if my logic is appropriate for the program. Kindly guide me.
#include<stdio.h>
int main()
{
int A = 0 , a = 0 , b = 0;
int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
printf("90 Degree rotation: \n");
printf("\n");
for(A = 2; A >= 0; A--)
{
for(a = 0; a < 3 ; a++)
{
for(b = 0; b < 3 ; b++)
{
if(b==A)
printf("%d\t",arr[a][b]);
}
}
printf("\n");
}
}
Input
1 2 3
4 5 6
7 8 9
Output
3 6 9
2 5 8
1 4 7
This is you matrix, with the axis you chose :
b ->
a 1 2 3
| 4 5 6
V 7 8 9
That is, for a fixed a for instance, if you increase b, you print "the next number" (provided b is not 2). Similarly, if you increase a with the same b, you take the same column, but the next line.
So, you can have the following pseudo program, to print a full column (on a line):
print_column(b):
for a from 0 to 2
print arr[a][b]
print newline
What do you want ? You want to print the following :
3 6 9
2 5 8
1 4 7
That is printing the last column, then the middle one, then the first one, which is done by the following pseudo-program:
print the 3rd column of arr
print the 2nd column of arr
print the 1st column of arr
or, more concisely :
for b from 2 to 0
print the b-th column of arr.
So, the final pseudo code is (inlining the print_column procedure):
for b from 2 to 0
for a from 0 to 2
print arr[a][b]
print newline
Or, in C:
for(b = 2; b >= 0 ; b--)
{
for(a = 0; a < 3 ; a++)
{
printf("%d\t",arr[a][b]);
}
printf("\n");
}
i am working on a program where the input is an ID of 9 numbers :
program checks if the id is correct or not by :-
checking if the string is formed by numbers only .
every number has a weight of 1 or 2 so it should be 1 2 1 2 1 2 1 2
1
multiply the weight and the number
if the number is bigger than 9 then add the numbers forming it .
if the number is from multiplication of 10 then the ID is correct ..
example :-
1 7 9 3 7 9 2 5 0-ID
1 2 1 2 1 2 1 2 1-Weight
1 14 9 6 7 18 2 10 0-num x weight
1 5 9 6 7 9 2 1 0-(4)
sum = 40 then it is a correct ID.
I wrote most of it but then i noticed that it has to be a string . so my questions are :
is there a way to put a string into an array?as doing it with an
array is way easier.
how do i locate a place in a string ? like if i want the third
character in a string how do i locate it?.
and here is the code that i did it does not work yet and it needs alot of changes but i guess i will put it anyways :-
#include<stdio.h>
#define N 9
void input(int num[N]);
int check(int num[N]);
int main()
{
int num[N],a;
input(num);
a = check(num);
if (a = 1)
printf("ID is correct");
else printf("ID is NOT correct");
}
void input(int num[N])
{
int i;
printf("Enter your ID (9digits) :-");
for (i = 0;i < N;i++)
scanf("%d",num[i]);
}
int check(int num[N])
{
int w[N] = { 1,2,1,2,1,2,1,2,1 },wxnum[N],i,tota[N],sum,g;
for (i = 0;i < N;i++)
wxnum[i] = num[i] * w[i];
for (i = 0;i < N;i++)
{
if (wxnum[i] > 9)
tota[i] = wxnum[i] / 10 + wxnum[i] % 10;
else tota[i] = wxnum[i];
}
sum = tota[0] + tota[1] + tota[2] + tota[3] + tota[4] + tota[5] + tota[6] + tota[7] + tota[8];
g = sum % 10;
if (g = 0)
return 1;
else
return 0;
}
Thanks everyone for your help.
You can get a string by doing
/*N is defined as 9 in your code.*/
/*Considering there is always a '\0' in every string, we should allocat N + 1 slot for your nine numbers and the extra '\0'.*/
char chStr[N + 1];
scanf("%s", chStr);
After you got the string, you can take advantage of the values of charactor '0' - '9' (their values are from 48 to 57 correspondingly) in ASCII table, and easily transfer the charactors into integers by doing:
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
}
If you are restrict on the type, you can transfer these char values into int values by adding extra two lines:
int num[N];
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
num[i] = (int) chStr[i];
}
Please note that my code didn't check the validation of user input. To make it more secure, you can use
scanf("%9s", chStr);
to declare the maximum length that the user can input.
I have to print this:
0
1 0 1
2 1 0 1 2
3 2 1 0 1 2 3
4 3 2 1 0 1 2 3 4
5 4 3 2 1 0 1 2 3 4 5
My code:
#include<stdio.h>
int main()
{
int i,j,k,l;
for(i=1;i<=6;i++)
{
for(j=6;j>i;j--)
{
printf(" ");
}
for(k=i-1;k>=0;k--)
{
printf("%d",k);
}
for(l=1;l<i;l++)
printf("%d",l);
printf("\n");
}
return 0;
}
My output:
0
101
21012
3210123
432101234
54321012345
I have just started coding in C so this is new to me. How do I put space between numbers so that the final output looks more elegant than it currently is?
I tried %-6d in printf("%d",k); to adjust the width but it had wrong indentation of the output.
That's easily fixed. Everywhere that you currently print a character (other than the newline), simply print that character followed by a space.
If you do that, you'll see the output you desire:
0
1 0 1
2 1 0 1 2
3 2 1 0 1 2 3
4 3 2 1 0 1 2 3 4
5 4 3 2 1 0 1 2 3 4 5
I won't show you the code since it's almost certainly classwork and you'll be a better coder if you nut it out yourself. But I will give you the tidbit that there are three lines that need to change. That should be more than enough to get the issue solved.
As a side note, this will also print a space at the end of each line, after the final digit. If that's not allowed, there are ways to fix it, primarily by changing the final loop so it doesn't output a space for the final item on the line.
It will also start failing miserably if you start trying to use two-digit numbers. To solve that, you need to know the widest number and use printf fields specifiers with widths. However, since it wasn't in the original spec, I haven't implemented that (see YAGNI).
If you wanted to implement something like that (with both the larger numbers and removed space at line end), you could use something like:
#include<stdio.h>
#define COUNT 15
int main(void) {
// Sanity check.
if (COUNT < 1) return 0;
// Get maximum width.
int width = 1, value = COUNT;
while (value > 9) {
value /= 10;
width++;
}
// For each line.
for (int line = 1; line <= COUNT; line++) {
// Output leading spaces.
for (int column = COUNT; column > line; column--)
printf("%*s ", width, "");
// Output descending digits.
for (int column = line - 1; column >= 0; column--)
printf("%*d ", width, column);
// Output ascending digits.
for (int column = 1; column < line; column++) {
printf("%*d", width, column);
if (column < line - 1) putchar(' ');
}
// Finish off line.
putchar('\n');
}
return 0;
}
It has the following advantages:
it allows for variable widths.
it uses more appropriately named (and fewer) loop variables.
it doesn't output the space at the end of each line.
Just don't use it as is if this is classwork, you'll almost certainly be found out.
use this..
add one space in in all three loops.
int i, j, k, l;
for (i = 1; i <= 6; i++) {
for (j = 6; j > i; j--) {
System.out.printf(" ");
}
for (k = i - 1; k >= 0; k--) {
System.out.printf("%d ", k);
}
for (l = 1; l < i; l++) {
System.out.printf("%d ", l);
}
System.out.printf("\n");
}
Instead of printf("%d",k) use printf("%d ",k).