I spent hours in printing a lower triangle in C. However, I just cannot figure out how to solve this same question with array.
Below is one of the solution I found on net:
int main(void)
{
char ch='A';
int i,j;
for(i=1;i<7;i++)
{
for(j=0;j<i;j++)
printf("%c",ch++);
printf("\n");
}
return 0;
}
Below is how I try to do the same thing:
#define SIZE 8
int main(void){
char Alphabet[SIZE];
int i, j;
for (i = 0, j = 'A'; i < SIZE, j < 'A' + SIZE; i++, j++){
Alphabet[i] = j;
}
for (i = 0; i <= 7; i++){
for (j = 0; j <= i; j++){
printf("%c", Alphabet[j+i]);
}
printf("\n");
}
return 0;
}
The result of the code above is :
A
BC
CDE
DEFG
EFGHI
FGHIJK
GHIJKLM
HIJKLMNO
What should I revise if I want to print as follow:
A
BC
DEF
GHIJ
KLMNO
PQRSTU
Thank you.
Keep a track of elements printed from the Alphabet array so far and in the inner loop start printing from next element onward. You can do:
#include <stdio.h>
#define SIZE 26
int main(void) {
char Alphabet[SIZE];
for (int i = 0; i < SIZE; i++) {
Alphabet[i] = 'A' + i;
}
// Or simply have the Alphabet array initialized like this
// char Alphabet[SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int k = 0;
for (int i = 0; i < 6; i++) {
for (int j = 0; j <= i && k < SIZE; j++) {
printf("%c", Alphabet[k++]);
}
printf("\n");
}
return 0;
}
Output:
# ./a.out
A
BC
DEF
GHIJ
KLMNO
PQRSTU
EDIT:
In the comments, a fellow SO contributor said that the above approach is same as the one OP already found as a solution and OP might be looking for approach of calculating the Alphabet array index using i and j only and without use of variable keeping track of array index. Below is the program which does not use any extra variable to keep the track of Alphabet array index to print characters in inner loop and calculating the index using i and j:
#include <stdio.h>
#define SIZE 26
#define ARRLOC(x) ((x * ((x + 1) / 2)) + ((x % 2 == 0) ? (x / 2) : 0))
int main(void) {
char Alphabet[SIZE];
for (int i = 0; i < SIZE; i++){
Alphabet[i] = 'A' + i;
}
// Or simply have the Alphabet array declared like this
// char Alphabet[SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < 6; i++){
for (int j = 0; j <= i && (ARRLOC(i) + j) < SIZE; j++){
printf("%c", Alphabet[ARRLOC(i) + j]);
}
printf("\n");
}
return 0;
}
Output:
# ./a.out
A
BC
DEF
GHIJ
KLMNO
PQRSTU
You can just have a third 'index' variable that keeps track of which letter to output across both loops (I've called this k in the code below). Also, you need to make your Alphabet array bigger (26 seems like a reasonable number); then, if that k variable gets past 'Z', we can simply loop back to 'A' using the modulo operator (%):
#include <stdio.h>
#define SIZE 26
int main(void)
{
char Alphabet[SIZE];
int i, j, k;
for (i = 0; i < SIZE; i++) Alphabet[i] = 'A' + i;
int k = 0;
for (i = 0; i <= 7; i++) {
for (j = 0; j <= i; j++) {
printf("%c", Alphabet[k % 26]); // If past the end, loop back with the "%" operator
++k;
}
printf("\n");
}
return 0;
}
Or we can make the code a little more 'succinct' (though perhaps less clear) by initializing the k variable at the start of the outer loop and incrementing at the end of the inner loop:
for (k = i = 0; i <= 7; i++) { // Initialize "k" here ...
for (j = 0; j <= i; j++, k++) { // .. but increment it here!
printf("%c", Alphabet[k % 26]); // If past the end, loop back with the "%" operator
}
printf("\n");
}
If you want an 8 by 8 pyramid, you won't have enough characters to do it using the alphabet (requires 36), so I made the alphabet repeat itself (u could also make it go to numeric instead?)
#define SIZE 8
int area(int size);
int main(void){
char Alphabet[area(SIZE)];
int i, j;
for (i = 0, j = 'A'; i < area(SIZE); i++, j++){
if (j > 'Z') j = 'A';
Alphabet[i] = j;
}
int idx=0;
for (i = 0; i < SIZE; i++){
for (j = 0; j <= i; j++){
printf("%c", Alphabet[idx++]);
}
printf("\n");
}
return 0;
}
int area(int size) {
if (size==1) return 1;
return size + area(size - 1);
}
Related
I want to put random numbers from 1 to 16 in a two-dimensional array without duplication.
I made a code that eliminates duplicates and puts new random numbers back into the array, but it keeps printing duplicate numbers.
Which part is wrong and why?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int A[4][4];
int i, j, k, l;
int num;
srand(time(NULL));
int count;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
//Re:
num = rand() % 16 + 1;
A[i][j] = num;
for(k = 0; k <= i; k++)
{
count = 0;
for(l = 0; l <= j; l++)
{
if(A[k][l] == num)
{
if(k != i && l != j)
{
j--;
count = 1;
break;
// goto Re;
}
}
}
if(count == 1)
break;
}
}
}
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
printf("%3d", A[i][j]);
}
printf("\n");
}
}
I want to put random numbers from 1 to 16 in a two-dimensional array without duplication. I made a code that eliminates duplicates and puts new random numbers back into the array, but it keeps printing duplicate numbers.
Put the numbers 1,…,16 into an array tmp.
Perform a Fisher-Yates shuffle on tmp.
Iterate through tmp to copy its elements to A using the mapping A[i/4][i%4] = tmp[i].
If you’re not convinced, try a few values of i by hand to assure yourself this works.
I want to randomize a to p without repetition.
int main(){
int array2[4][4];
bool arr[100]={0};
int i;
int j;
srand(time(NULL));
for(i=0; i<=3; i++){
for(j=0; j<=3; j++){
int randomNumber1;
randomNumber1 = (rand() % (82-65+1))+65;
if (!arr[randomNumber1])
{
printf("%c ",randomNumber1);
array2[i][j]=randomNumber1;
}
else
{
i--;
j--;
arr[randomNumber1]=1;
}
}
printf("\n");
}
return;
the output still has repeat alphabet. I want to have the output in 4x4 with with all a to p without it repeating.
There are some errors in your code. IMHO the most serious is that arr[randomNumber1]=1; is is the wrong branch of the test. That means that your current code does not invalidate once a number was used but only if it has already been invalidated => if you control the arr array at the end of the program all value are still 0.
That is not all. When you get a duplicate, you should only reset the inner loop, and you are currently off by 2 in your maximum ascii code: you go up to R when you want to stop at P.
Your code should be:
for (i = 0; i <= 3; i++) {
for (j = 0; j <= 3; j++) {
int randomNumber1;
randomNumber1 = (rand() % (81 - 65)) + 65;
if (!arr[randomNumber1])
{
printf("%c ", randomNumber1);
array2[i][j] = randomNumber1;
arr[randomNumber1] = 1;
}
else
{
//i--;
j--;
}
}
printf("\n");
}
But this kind of code is terribly inefficient. In my tests it took 30 to 60 steps to fill 16 values, because random can return duplicates. This is the reason why you were advised in comments to use instead the modern algorithm for Fisher-Yates shuffle:
int main() {
int array2[16];
unsigned i, j, k=0;
// initialize array with alphabets from A to P
for (i = 0; i < sizeof(array2); i++) {
array2[i] = 'A' + i;
}
// Use Fisher-Yates shuffle on the array
srand(time(NULL));
for (i = 15; i > 0; i--) {
j = rand() % (i + 1);
if (j != i) {
int c = array2[i];
array2[i] = array2[j];
array2[j] = c;
}
}
// Display a 4x4 pattern
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
printf("%c ", array2[k++]);
}
printf("\n");
}
return 0;
}
Which shuffles the array in only 16 steps.
Here is the outline
// Need some #includes here - exercise for the reader
char items[] = "abcdefghijklmnopqrstuvwxyz";
int len = sizeof(items);
srand(time(NULL));
while (len > 0) {
int r = rand() % len;
printf("%c", items[r]);
len--;
items[r] = items[len];
}
This should do the trick to print the whole alphabet in random order without repeats. Modify to do what you need it to do
I'm new to C and I'm just trying to print out a two 2 array.
This bug has been annoying me all day and I'm not really sure whats going on.
#include<stdio.h>
void run(int);
main()
{
run(5);
return 0;
}
//Have to make it a character array as it needs to
//store numbers AND commas.
run(int x)
{
int size = 2*x -1;
char array[size][size];
int i = 0;
int j = 0;
for( i; i < size; i++){
for(j; j< size; j++){
array[i][j] = '1';
}
}
int k = 0;
int l = 0;
for( k; k < size; k++){
for(l; l< size; l++){
printf( "%c" , array[l][k]);
}
printf("%\n", "");
}
}
This is the output I get:
1%
%
%
%
%
%
%
%
%
You code has several mistakes:
The biggest problem is that your not initializing your loop counters where you should:
for(i; i < size; i++){
for(j; j < size; j++){
With that, i & j are left as they were prior to the for statement. The first section of these statements does nothing at all. While that's harmless for i (since it's initialized to 0 before the for), that's devastating for j, which never goes back to 0. Your code should be:
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
The same issue exists with k & l, and the same fix should be applied:
for(k = 0; k < size; k++){
for(l = 0; l < size; l++){
Next, you're "rotating" access in your array. When you fill the array with values, you have i in your outer loop and j in the inner loop, and you use them as [i][j]:
array[i][j] = '1';
Think of that as Out & In --> [Out][In].
When you print the array, you "rotate" that, k is outer & l is inner, and you use them as [l][k]:
printf("%c", array[l][k]);
That's like doing [In][Out].
While that's not a problem with all values being identical ('1'), and the matrix being square (width == height), it won't work with other values or dimensions, and is confusing.
Last, you're attempt to print a new line is wrong. You have a % specifier, but your not really using any valid character after that, and you don't need that anyway, just print:
printf("\n");
So, all together, here's what the code should be:
run(int x)
{
int size = 2*x -1;
char array[size][size];
int i,j;
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
array[i][j] = '1';
}
}
int k, l;
for(k = 0; k < size; k++){
for(l = 0; l < size; l++){
printf("%c", array[k][l]);
}
printf("\n");
}
}
(And as a side note, k & l are not really required, you can simply reuse i & j)
Hello i am trying to use counting sort to sort numbers that i read from a file. this is my code:
void CountingSort(int array[], int k, int n)
{
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++)
{
C[i] = 0;
}
for (j = 1; j <= n; j++)
{
C[array[j]] = C[array[j]] + 1;
}
for (i = 1; i <= k; i++)
{
C[i] = C[i] + C[i-1];
}
for (j = 1; j <= n; j++)
{
B[C[array[j]]] = array[j];
C[array[j]] = C[array[j]] - 1;
}
printf("The Sorted array is : ");
for (i = 1; i <= n; i++)
{
printf("%d ", B[i]);
}
}
void max(int array[],int *k,int n){
int i;
printf("n je %d\n",n);
for (i = 0; i < n; i++)
{
if (array[i] > *k) {
*k = array[i];
}
}
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k=0,n,x,z;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
max(array,&k,n);
printf("Max je %d\n",k);
CountingSort(array,k,n);
return 0;
}
i have no errors but when i start my program i get Segmentation fault error. pls help! (dont read this bot is asking me to write some more details but i have none so i just write some random words so i can post my question and hopefully get an answer)
The problem is that your implementation of the counting sort is incorrect: it uses arrays as if they were one-based, while in C they are zero-based.
After carefully going through your loops and fixing all situations where you use a for loop that goes 1..k, inclusive, instead of the correct 0..k-1, the code starts to work fine:
int i, j;
int B[100], C[1000];
for (i = 0; i <= k; i++){
C[i] = 0;
}
for (j = 0; j < n; j++){
C[array[j]]++;
}
for (i = 1; i <= k; i++){
C[i] += C[i-1];
}
for (j = 0; j < n; j++) {
B[--C[array[j]]] = array[j];
}
printf("The Sorted array is : ");
for (i = 0; i < n; i++) {
printf("%d ", B[i]);
}
Demo.
Note: I modified some of the operations to use C-style compound assignments and increments/decrements, e.g. C[array[j]]++ in place of C[array[j]] = C[array[j]] + 1 etc.
The problem most likely is here
int B[100], C[1000]; // C has space for numbers up to 999
...
for (i = 1; i <= k; i++)
C[i] = C[i] + C[i-1]; // adding up till C[k] == sum(array)
for (j = 0; j < n; j++)
B[C[array[j]]] = array[j]; // B has space up to 99, but C[k] is sum(array)
so you're reserving space for C for a highest value of 999 but in B you're assuming that the sum of all input values is less than 100...
the resolution of your problem is to first probe the input array and get the maximum and the sum of all input values (and minimum if the range may be negative) and allocate space accordingly
edit: you probably meant j < n and not j <= n
Adding to dasblinkenlight's spot-on answer:
Is your input data guaranteed to be in the range [0, 999]? If it isn't, it's obvious that segmentation faults can and will occur. Assume that the maximum value of array is 1000. C is declared as
int C[1000];
which means that C's valid indices are 0, 1, 2, ... 999. But, at some point, you will have the following:
C[array[j]] = ... /* whatever */
where array[j] > 999 so you will be attempting an out-of-bounds memory access. The solution is simple: probe array for its maximum value and use dynamic memory allocation via malloc:
/* assuming k is the maximum value */
int * C = malloc((k + 1) * sizeof(int));
Note: an alternative to this, which would also nullify the need for an initialization loop to make all elements of C equal to 0, would be to use calloc, which dynamically allocates memory set to 0.
// allocate C with elements set to 0
int * C = calloc(k + 1, sizeof(int);
Another important factor is the range of your running indices: you seem to have forgotten that arrays in C are indexed starting from 0. To traverse an array of length K, you would do:
for (i = 0; i < K; ++i)
{
processArray(array[i]);
}
instead of
for (i = 1; i <= K; ++i)
{
processArray(array[i]);
}
I would like to return a shape(trapezium) with bases 6 and 3 given integers 3 and 4 and a char.
I have tried implementing this with code below but I am getting a rectangle instead
#include <stdio.h>
char my_array[];
char *ptr;
int m = 3,n =4;
int main(void)
{
int i,j;
ptr = &my_array[0];
for (j = 0;j < n ;++j)
{
for (i = 0; i < m+n-1; i++)
{
my_array[i] = '*';
printf("%c ",my_array[i]);
}
printf("\n");
}
return 0;
}
I would like to know how I can reduce the length of each row of the result above to get the shape i need.Any ideas?
You probably meant to use i < m + j - 1 in your second for loop:
#include <stdio.h>
const int m = 3, n = 4;
int main(void){
int i, j;
const char symb = '*';
for (j = 0; j < n ;++j){
for (i = 0; i < m + j - 1; i++)
printf("%c ",symb);
printf("\n");
}
return 0;
}