what is worng with me? bubblesort about string - c

#include <stdio.h>
#include <string.h>
void bubblesort(int n, char *ptr[]){
char *tmp;
for (int i = 0; i < n; i++){
for (int j = 0 ; j < n; j++){
if(strcmp(*(ptr+i) , *(ptr+j))>0){
strcpy(tmp , *(ptr+i));
strcpy(*(ptr+i) , *(ptr+j));
strcpy(*(ptr+j) , tmp);
}
}
}
//printf("\n",ptr+0,ptr+1,ptr+2,ptr+3,ptr+4,ptr+5,ptr+6,ptr+7,ptr+8,ptr+9); **<= without this line my code doesn't executive**
}
int main()
{
int n;
scanf("%d\n", &n);
char str[10][20];
for (int i = 0; i < n; i++)
gets(str[i]);
char *ptr[10];
for (int i = 0; i < n; i++)
ptr[i] = str[i];
bubblesort(n, ptr);
for (int i = 0; i < n; i++)
puts(ptr[i]);
}
C:\Users\kk\Desktop\C>a
10
banana
kiwi
apple
tomato
lemon
melon
pear
blueberry
strawberry
orange
tomato
strawberry
pear
orange
melon
lemon
kiwi
blueberry
banana
apple
C:\Users\kk\Desktop\C>
with out above line
C:\Users\kk\Desktop\C>a
10
banana
kiwi
apple
tomato
lemon
melon
pear
blueberry
strawberry
orange
C:\Users\kk\Desktop\C>
`

The inner loop should use j and j + 1 not i and j, and the condition on j for that loop is incorrect.
As you are operating on pointers to string you can just swap those instead of copying the strings themselves. It's clearer to write that swap() function instead of doing it inline.
Finally, gets() is a not safe to use, and for these types of problems it's much better to hard-code a test case.
#include <stdio.h>
#include <string.h>
void swap(char **a, char **b) {
char *tmp = *a;
*a = *b;
*b = tmp;
}
void bubblesort(size_t n, char *ptr[n]) {
if(n < 2) return;
for (size_t i = 0; i < n - 1; i++)
for (size_t j = 0; j < n - i - 1; j++)
if(strcmp(ptr[j], ptr[j + 1]) > 0)
swap(&ptr[j], &ptr[j + 1]);
}
int main() {
char *a[] = {
"Lorem",
"ipsum",
"dolor",
"sit",
"amet"
};
size_t n = sizeof a / sizeof *a;
bubblesort(n, a);
for (int i = 0; i < n; i++)
puts(a[i]);
}
and here is the output:
Lorem
amet
dolor
ipsum
sit

Related

shuffling the 2d array deck which represents the 52 cards

i have this program that prints th2 52 cards of a deck in order and then should print them randomly shuffled. I tried using many ways, but this one looked the most logically correct for me so Can you please tell me my mistake in shuffling and a solution to fix it, so my program will print the 52 cards shuffled.
#include <stdio.h>
#define DECK_SIZE 52
#define SUIT_SIZE 4
#define FACE_SIZE 13
char* suit[SUIT_SIZE] = {"Hearts", "Diamonds", "Clubs", "Spades"};
char* face[FACE_SIZE] = {"Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Jack", "Queen", "King"};
char* deck[SUIT_SIZE][FACE_SIZE];
char * card_name_create(char* face, char* suit){
size_t face_len = strlen(face);
size_t suit_len = strlen(suit);
size_t of_len = 4;
char of[5] = " of ";
// The size id the size of two strings, than the size of " of " and the '\0'
char * full_name = malloc(sizeof(char)*(face_len+suit_len+of_len+1));
for (size_t i = 0; i < face_len; i++){
full_name[i] = face[i];
}
for (size_t i = face_len; i < face_len+of_len; i++){
full_name[i] = of[i-face_len];
}
for (size_t i = face_len+of_len; i < face_len+of_len+suit_len; i++){
full_name[i] = suit[i - (face_len+of_len) ];
}
full_name[face_len+of_len+suit_len] = '\0';
return full_name;
}
void initialiseDeck(){
for (int i = 0; i < SUIT_SIZE; i++){
for (int j = 0; j < FACE_SIZE; j++){
char * c = card_name_create(face[j],suit[i]);
deck[i][j] = c;
}
}
}
void display(){
for(int i = 0; i < SUIT_SIZE; ++i)
for(int j = 0; j < FACE_SIZE; ++j)
printf("%s\n", deck[i][j]);
}
void shuffleDeck(){
int size = DECK_SIZE;
if (size > 1){
int i;
for (i = 0; i < size - 1; i++){
int j = rand() % DECK_SIZE;
const char* temp = deck[j];
deck[j] = deck[i];
deck[i] = temp;
}
}
}
int main(){
initialiseDeck();
printf("=========================");
printf("Cards Without Shuffling - ");
printf("=========================\n");
display();
srand (time(NULL));
shuffleDeck();
printf("cards after shuffling\n");
int p;
for (p = 0; p < DECK_SIZE; p++) {
printf("%i: %s\n", p, deck[p]);
}
return 0;
}
If you are going to be shuffling anyway, there is no point in separating the cards by suit and rank... you should just have a 1-dimensional array int deck[DECK_SIZE];, and you can shuffle it with a function like this:
// Caller should seed the PRNG before calling this function, using srand
int *shuffle(int deck[], const int size)
{
for (int i = 0; i < size; ++i) {
int j = rand() % (size - i) + i;
int tmp = deck[i];
deck[i] = deck[j];
deck[j] = tmp;
}
return deck;
}

A program sort array by remainder 3

I was requested to write an effecient function with running time n which sort array by the remainder of 3 the program puts the elements which the remainder from dividing in 3 is 0 afterwards the elements that the remainder is 1 and afterwards 2
for example the array {7, 16, 3, 28, 12, 31, 14, 12}
will be sortes that way {12, 3, 12, 28, 16, 31, 7, 14}
so I tries to write an efficient function but it have not cover all cases and does not works for all arrays
int arr[] = { 7,16,3,28,12,31,14,12 };
int rem0 = 0, rem1 = 1, rem2 = 2;
for (int i = 0; i < 8; i++) {
if (arr[i] % 3 == 0)
rem0++;
if (arr[i] % 3 == 1)
rem1++;
if (arr[i] % 3 == 2)
rem2++;
}
int k = rem0, p = 0, m = 0 = 0;
for (int i = 0; i < 8; i++) {
while (rem0-k){
swap(&arr[i], &arr[rem0 - k]);
k--;
}
if (arr[i] % 3 == 1 && rem0+m<7) {
swap(&arr[i], &arr[rem0 + m]);
m++;
}
if (arr[i] % 3 == 1 && rem0 + rem1 + p<7) {
swap(&arr[i], &arr[rem0+rem1 + p]);
p++;
}
}
for (int l = 0;l <8;l++) {
printf("%d\n", arr[l]);
}
}
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
swap switch elements,
Can anyone tells me how can I fix that?
thanks:)
Since you want your function to run in O(n) time, you cannot sort the array completely. All you need to do is put all the elements in 3 buckets.
The following algorithm runs in 2 phases.
//First we count the number of elements in each bucket
int count[3] ={0, 0, 0};
for (int i = 0; i < NUM_ELEMENTS; i++) {
count[arr[i]%3]++;
}
Now that we have the number of elements, we can calculate the offsets of each bucket and create and output array
int output[NUM_ELEMENTS]; // In place bucketing can also be done using swaps
count[2] = count[0] + count[1];
count[1] = count[0];
count[0] = 0;
for (int i = 0; i < NUM_ELEMENTS; i++) {
output[count[arr[i]%3]] = arr[i];
count[arr[i]%3]++;
}
// Finally print the array
for (int i = 0; i < NUM_ELEMENTS; i++) {
printf("%d", output[i]);
}
Demo on Ideone
Here is the solution which you are looking for which uses the same array:
#include <stdio.h>
#define REMINDER 3
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,0};
int arr_size = sizeof(arr)/sizeof(arr[0]);
int idx=0;
for (int r=0; r<REMINDER; r++) {
for (int i=0; i<arr_size; i++) {
if (arr[i]%REMINDER==r) {
swap(&arr[idx++], &arr[i]);
}
}
}
for (int i=0; i<arr_size; i++) {
printf("%d ", arr[i]);
}
return 0;
}
Here is a another solution which is just simpler by using other place to store the result:
#include <stdio.h>
#define REMINDER 3
#define ARR_SIZE 10
int main()
{
int arr[ARR_SIZE] = {1,2,3,4,5,6,7,8,9,0};
int arr_sorted[ARR_SIZE];
int idx=0;
for (int r=0; r<REMINDER; r++) {
for (int i=0; i<ARR_SIZE; i++) {
if (arr[i]%REMINDER==r) {
arr_sorted[idx++]=arr[i];
}
}
}
for (int i=0; i<ARR_SIZE; i++) {
printf("%d ", arr_sorted[i]);
}
return 0;
}
Here's a 1-pass in-place Dutch national flag algorithm implementation (thanks to #Virgile who pointed out the algorithm)
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
// Dutch National Flag (see xlinux.nist.gov/dads/HTML/DutchNationalFlag.html)
void sort3dnf(int *a, size_t n) {
int *bot = a;
int *mid = a;
int *top = a + n - 1;
while (mid <= top) {
switch (*mid % 3) {
default: swap(bot++, mid++); break;
case 1: mid++; break;
case 2: swap(mid, top--); break;
}
}
}
See ideone.com/6QXXCN
hey thanks for the advice
sadly we had requested to write the code
without any added array
I will be very glad if you could help me to
solve the issue
thanks :)
hey thanks for the advice sadly we had requested to write the code without any added array I will be very glad if you could help me to solve the issue thanks :)
Here is the answer without adding any extra array:
#include <stdio.h>
#define REMINDER 3
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,0};
int arr_size = sizeof(arr)/sizeof(arr[0]);
int idx=0;
for (int r=0; r<REMINDER; r++) {
for (int i=0; i<arr_size; i++) {
if (arr[i]%REMINDER==r) {
swap(&arr[idx++], &arr[i]);
}
}
}
for (int i=0; i<arr_size; i++) {
printf("%d ", arr[i]);
}
return 0;
}

How to insert multiple elements into an array in c

The program is suppose to print a 16 by 16 grid and insert multiple elements horizontally at random within the grid it works fine when i try inserting a single element in the grid but when I try multiple it inserts symbols into the grid. I Would like to now why this occurs. Here's a copy of my code so far :
#include <stdio.h>
#include <stdlib.h>
char **create2DArray();
#define WIDTH 16
#define HEIGHT 16
char** myArray; //global array
void main()
{
myArray = create2DArray();
}
char **create2DArray(){
int i,j;
char **array = (char **) malloc(sizeof(char *) * WIDTH);
for(i=0; i<WIDTH; i++)
array[i] = (char *) malloc(sizeof(char) * HEIGHT);
void insertHorizontally(char* word, char** array);
srand(time(NULL));
int WIDTH_1 = (rand()%15)+ 1;
int HEIGHT_1 = (rand()%15) + 1;
int insert;
char* word[] = {"CAT","DOG",};
insert = strlen(word);
for(i=0; i<WIDTH; i++){
for(j=0; j<HEIGHT; j++){
array[i][j] = '.';
}
}
for (j = HEIGHT_1; j < HEIGHT_1 + insert; j ++) {
array[WIDTH_1][j] = word[j - HEIGHT_1];
}
void printArray(char** array);
for(i=0; i<WIDTH; i++){
for(j=0; j<HEIGHT; j++){
printf("%c ", array[i][j]);
}
printf("\n");
}
return array;
}
Any help,tips or advice would be appreciated :)
I hope this help you. It has compiled in Linux. You should try the more readable source for receiving good help here.
Note: If the random function gives the last index of columns in a row, it is possible that your element inserted partially.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **create2DArray();
#define WIDTH 16
#define HEIGHT 16
char** myArray; //global array
char **create2DArray(){
int i,j;
char **array = (char **) malloc(sizeof(char *) * WIDTH);
for(i=0; i<WIDTH; i++)
array[i] = (char *) malloc(sizeof(char) * HEIGHT);
return array;
}
void insertHorizontally(char** word, int num, char** array)
{
srand(time(NULL));
int i, j, k;
int WIDTH_1;
int HEIGHT_1;
int insert;
for(i=0; i<WIDTH; i++){
for(j=0; j<HEIGHT; j++){
array[i][j] = '.';
}
}
for(k = 0; k < num; k++){
insert = strlen(word[k]);
WIDTH_1 = (rand() % WIDTH);
HEIGHT_1 = (rand() % HEIGHT);
for (i= 0, j = HEIGHT_1; i < insert && j < HEIGHT ; j ++, i ++)
array[WIDTH_1][j] = word[k][j - HEIGHT_1];
}
}
void printArray(char** array){
int i, j;
for(i=0; i<WIDTH; i++){
for(j=0; j<HEIGHT; j++){
printf("%c ", array[i][j]);
}
printf("\n");
}
}
void main()
{
myArray = create2DArray();
char *word[] = {{"CAT"},{"DOG"},{"FOX"}};
insertHorizontally(word, sizeof(word)/sizeof(char *), myArray);
printArray(myArray);
}

Trying to implement a word search in C

As the title says, I'm trying to make a word search in C. However, when I run what I have, I'm getting an aborted(core dumped) message.
My code:
void lefttoright(int rowcol, char **matrix, char* find){
int i, j, k, q, len, count = 0;
len = strlen(find);
for (i = 0; i < rowcol; i++){
for (j = 0; j < rowcol; j++){
if (matrix[i][j] == find[0]){
char* correct = malloc(sizeof(char) * 20);
for (q = j; q < rowcol; q++){
for (k = 0; k < len; k++){
if (matrix[i][q] == find[k]){
correct[k] = matrix[i][q];
}
}
if (strcmp(correct, find) == 0){
count++;
printf("%s\n", correct);
printf("%d\n", count);
}
}
free(correct);
}
else continue;
}
}
printf("%d", count);
}
.
if (strcmp(correct, find) == 0){
count++;
printf("%s\n", correct);
printf("%d\n", count);
}
prints
bagel
1
bagel
2
bagel
3
bagel
4
bagel
5
bagel
6
bagel
7
bagel
8
bagel
9
bagel
10
bagel
11
bagel
12
bagel
13
Aborted (core dumped)
What is making it abort? Also, what do I need to do differently to make count == 1 (the word only appears once)?
My entire program if needed:
#include <stdio.h>
#include <stdlib.h>
#include "scanner.h"
#include <string.h>
#include <ctype.h>
char** matrixMaker(int argc, char **argv);
void displayMatrix(int rowcol, char **matrix);
void lefttoright(int rowcol, char **matrix, char* find);
int main(int argc, char **argv){
FILE *fp = fopen(argv[2], "r");
int rowcol = atoi(argv[1]);
int a, i = 0, j;
unsigned char cha;
char **matrix;
matrix = malloc( sizeof(char *) * rowcol);
for (a=0; a<20; a++)
matrix[a] = malloc( sizeof(char) * rowcol);
for (i = 0; i < rowcol; i++){
for (j = 0; j < rowcol; j++){
cha = tolower((unsigned char)readChar(fp));
matrix[i][j] = cha;
}
}
char* find = malloc(sizeof(char) * 20);
displayMatrix(rowcol, matrix);
printf("Enter a word to find in the puzzle : \n");
scanf("%s", find);
while(find[i]){
putchar(tolower((unsigned char)find[i]));
i++;
}
lefttoright(rowcol, matrix, find);
free(matrix);
return 0;
}
void displayMatrix(int rowcol, char **matrix){
int r,c;
for (r = 0; r < rowcol; ++r){
for (c = 0; c < rowcol; ++c){
printf("%c",matrix[r][c]);
}
printf("\n");
}
}
void lefttoright(int rowcol, char **matrix, char* find){
int i, j, k, q, len, count = 0;
len = strlen(find);
for (i = 0; i < rowcol; i++){
for (j = 0; j < rowcol; j++){
if (matrix[i][j] == find[0]){
char* correct = malloc(sizeof(char) * 20);
for (q = j; q < rowcol; q++){
for (k = 0; k < len; k++){
if (matrix[i][q] == find[k]){
correct[k] = matrix[i][q];
}
}
if (strcmp(correct, find) == 0){
count++;
printf("%s\n", correct);
printf("%d\n", count);
}
}
free(correct);
}
else continue;
}
}
printf("%d", count);
}

Making a shape from characters in an array in c

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;
}

Resources