char in string is not in order wanted - string

I am a beginner and I need some help here. This program prints out the frequency of char in the string, e.g. if user enters zzaaa it prints out a3z2 and what I need to print is z2a3 since z is entered first before a. But I am having a hard time switching the order around. Thanks in advance!
int main
{
int ib, i=0, j=0, k=0;
int count[26] = {0};
char chh[3][10];
for (ib = 0; ib < 3; ib++) // get 3 input
gets(chh[ib]);
for (i = 0; i < 3; i++)
{
for (j = 0; j < 10; j++)
{
if (chh[i][j] >= 'a' && chh[i][j] <= 'z')
{
count[chh[i][j] - 'a']++;
}
}
for (k = 0; k < 26; k++)
{
if (count[k] != 0) // if array location is not equals to 0
printf("%c%d", k + 'a', count[k]);
}
memset(count, 0, sizeof(count)); //reset integer array
printf("\n");
}

It prints a before z because you arranged count from a to z by alphabetic priority not entering priority:
count[chh[i][j] - 'a']
if you want to print them by entering priority you should change it. there are several ways to do this. like this:
#include <stdio.h>
#include <string.h>
int main()
{
int ib, i=0, j=0,k=0, kk=0,c=0,found=0;
int count[26][2];
char chh[3][10];
for (ib = 0; ib < 3; ib++) // get 3 input
gets(chh[ib]);
printf("output is:\n");
for (i=0;i<26;i++)
{
count[i][0]=0;
count[i][1]=0;
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 10; j++)
{
if (chh[i][j] >= 'a' && chh[i][j] <= 'z')
{
found=0;
for (c=0;c<kk;c++)
if (count[c][0]==chh[i][j])
{
count[c][1]++;
found=1;
break;
}
if (!found)
{
count[c][0]=chh[i][j];
count[c][1]++;
kk++;
}
}
}
for (k = 0; k < 26; k++)
{
if (count[k][1] != 0) // if array location is not equals to 0
printf("%c%d", count[k][0], count[k][1]);
}
memset(count, 0, sizeof(count)); //reset integer array
printf("\n");
}
}

Related

Why is my integer variable being added to my other integer variable?

I am writing a program that counts the amount of letters and words in a string given by the user. For some reason, the number of words is being added to the number of letters. If there is 3 words in the sentence and 12 letters, then it says that there is 15 words. My code is below:
#include <cs50.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int storeLetters[] = {};
int storeWords[] = {};
// declare functions
int count_letters(string text);
int count_words(string text);
int main(void)
{
// ask user for text passage
string text = get_string("Text: ");
int numOfLetters = count_letters(text);
printf("%d",numOfLetters);
printf(" letters\n");
int numOfWords = count_words(text);
printf("%d",numOfWords);
printf(" words\n");
}
int count_letters(string text)
{
int amountOfLetters = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (isalpha(text[i]))
{
storeLetters[i] += 1;
amountOfLetters += storeLetters[i];
}
else
{
storeLetters[i] += 0;
amountOfLetters += storeLetters[i];
}
}
return amountOfLetters;
}
int count_words(string text)
{
int amountOfWords = 0;
for (int x = 0, n = strlen(text); x < n; x++)
{
if (text[x] == '?' || text[x] == '!' || text[x] == '.' || text[x] == ' ')
{
storeWords[x] += 1;
amountOfWords += storeWords[x];
}
else
{
storeWords[x] += 0;
amountOfWords += storeWords[x];
}
}
return amountOfWords;
}
storeLetters and storeWords are arrays, which you initialize to zero length. If you access storeLetters[0] (or any other index), you go past the end. It's not gonna work.
You don't need those variables at all. Just increment amountOfLetters directly.
int count_letters(string text)
{
int amountOfLetters = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (isalpha(text[i]))
{
amountOfLetters += 1;
}
}
return amountOfLetters;
}

my program does not continue compiling if I don't type any letter

I am solving the problem set1_ credit in cs50. the program woks fine, however after entering the credit card number, i need to enter any letter in the keyboard in order for the program to give me the answer.
here is my code
# include <cs50.h>
# include <stdio.h>
# include <math.h>
long credit(void);
int main(void)
{
long long num = credit();
long long num2 = num;
int c = log10(num), i, sum , sum1, sum2 = 0, digits[c], divid[c], remind[c], total[c], cards[c];
scanf("%d", &c);
for ( i = 0; i <= c ; i++)
{
digits[c-i] = num % 10;
num = num /10;
scanf("%d", &digits[c-i]);
}
if ( c % 2 != 0)
{
for ( i = 0 ; i <= c ; i++)
{
if ( i % 2 == 0 )
{
digits[i] = digits [i] * 2;
}
else
{
digits[i] = digits [i];
}
}
}
else
{
for ( i= 0 ; i <= c ; i++)
{
if ( i % 2 != 0)
{
digits [i] = digits[i] * 2;
}
else
{
digits[i] = digits[i];
}
}
}
for ( i = 0; i <= c; i++ )
{
remind[i] = digits[i] % 10;
}
//printf("\n");
for (i = 0; i <= c; i++)
{
divid[i] = digits[i] / 10;
}
for ( i = 0; i <= c; i++ )
{
total[i] = remind[i] + divid[i];
}
for ( i = 0; i <= c ; i++ )
{
sum = sum + total[i];
}
// recreate the card's number in a form of an array
for ( i = 0; i <= c ; i++)
{
cards[c-i] = num2 % 10;
num2 = num2 /10;
scanf("%d", &cards[c-i]);
}
// check the nature and the validity of a card
int cards1 = cards[1];
if (sum % 10 == 0 && cards[0] == 3)
{
if (c == 15 )
{
switch (cards [1])
{
case 4: printf("AMEX");
break;
case 7: printf("AMEX");
break;
}
}
//return 0;
printf("AMEX");
}
else if (cards[0] == 5 && sum % 10 == 0)
{
if (c == 16)
{
switch (cards [1])
{
case 1: printf("MASTERCARD");
break;
case 2: printf("MASTERCARD");
break;
case 3: printf("MASTERCARD");
break;
case 4: printf("MASTERCARD");
break;
case 5: printf("MASTERCARD");
break;
}
}
//return 0;
printf("MASTERCARD\n");
}
else if (cards[0] == 4 && sum % 10 == 0)
{
switch (c)
{
case 13: //printf("VISA\n");
break;
case 16: //printf("VISA\n");
break;
}
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
printf("\n");
}
// get number of digits of an integer
long credit(void)
{
long long n;
do
{
n = get_long_long("Number: ");
}
while (log10(n) < 12 || log10(n) > 16);
return n;
}
I would be very grateful if anyone could help me solve this issue.
thanks in advance.
From man scanf:
The scanf() function reads input from the standard input stream stdin
The program is waiting for keyborad input (stdin) at one of the several scanf commands.
NB This question description is misleading because the program does compile, it (seemingly) stops running until keyboard input.

Select in loop - work all the time - linux

I got next question about select:
How to make select in loop ?
I try to do like that:
struct timeval timeout;
int sel;
size_t rozmiar = sizeof(pid_t);
char buf[rozmiar];
int i;
FD_ZERO(&set);
for(i = 0; i< val; i++)
{ FD_SET(fd[i][0], &set); // val -> N pipe2
}
timeout.tv_sec = 2;
timeout.tv_usec = 0;
while(1)
{
sel = select(val+1,&set,NULL,NULL,&timeout);
if(sel < 0)
perror("select");
else if(sel == 0)
printf("No communicate \n");
else{
for(i = 0; i < val; i++)
{
if(FD_ISSET(fd[i][0],&set))
{
while(read(fd[i][0],&buf,rozmiar) > 0)
write(1,&buf,rozmiar);
} // check if exist and write to stdout
}
} // end SELECT
timeout.tv_sec = 2;
timeout.tv_usec = 0;
}
But there all the time show: ,, no communicate". Is it the correct way to create select which work all the time? I am not sure so I prefer to ask. I try to find information in books but with no lucky.
The set is changed by select, you need to refill it each time

how can I display unsigned char with SetWindowText

I want to display unsigned char value with SetWindowText, but nothing displayed on label
code
DWORD WINAPI fill_matrix(LPVOID lpParameter)
{
unsigned char a = 'h';
for (int i = 0; i < 8; i++){
for (int j = 0; j <8; j++)
{
SetWindowText(hWndLabel[i * 8 + j], (LPCTSTR)a);
}
}
return 0;
}
I configured my project proprieties with unicode
SetWindowText requires string, not a single charater.
You should use SetWindowTextA, which explicitly use ANSI characters.
Fixed code:
DWORD WINAPI fill_matrix(LPVOID lpParameter)
{
unsigned char a = 'h';
for (int i = 0; i < 8; i++){
for (int j = 0; j <8; j++)
{
char window_text[2] = {a, '\0'};
SetWindowTextA(hWndLabel[i * 8 + j], window_text);
}
}
return 0;
}

How to parallelize Sudoku solver using Grand Central Dispatch?

As a programming exercise, I just finished writing a Sudoku solver that uses the backtracking algorithm (see Wikipedia for a simple example written in C).
To take this a step further, I would like to use Snow Leopard's GCD to parallelize this so that it runs on all of my machine's cores. Can someone give me pointers on how I should go about doing this and what code changes I should make? Thanks!
Matt
Please let me know if you end up using it. It is run of the mill ANSI C, so should run on everything. See other post for usage.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
short sudoku[9][9];
unsigned long long cubeSolutions=0;
void* cubeValues[10];
const unsigned char oneLookup[64] = {0x8b, 0x80, 0, 0x80, 0, 0, 0, 0x80, 0, 0,0,0,0,0,0, 0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ifOne(int val) {
if ( oneLookup[(val-1) >> 3] & (1 << ((val-1) & 0x7)) )
return val;
return 0;
}
void init_sudoku() {
int i,j;
for (i=0; i<9; i++)
for (j=0; j<9; j++)
sudoku[i][j]=0x1ff;
}
void set_sudoku( char* initialValues) {
int i;
if ( strlen (initialValues) != 81 ) {
printf("Error: inputString should have length=81, length is %2.2d\n", strlen(initialValues) );
exit (-12);
}
for (i=0; i < 81; i++)
if ((initialValues[i] > 0x30) && (initialValues[i] <= 0x3a))
sudoku[i/9][i%9] = 1 << (initialValues[i] - 0x31) ;
}
void print_sudoku ( int style ) {
int i, j, k;
for (i=0; i < 9; i++) {
for (j=0; j < 9; j++) {
if ( ifOne(sudoku[i][j]) || !style) {
for (k=0; k < 9; k++)
if (sudoku[i][j] & 1<<k)
printf("%d", k+1);
} else
printf("*");
if ( !((j+1)%3) )
printf("\t");
else
printf(",");
}
printf("\n");
if (!((i+1) % 3) )
printf("\n");
}
}
void print_HTML_sudoku () {
int i, j, k, l, m;
printf("<TABLE>\n");
for (i=0; i<3; i++) {
printf(" <TR>\n");
for (j=0; j<3; j++) {
printf(" <TD><TABLE>\n");
for (l=0; l<3; l++) { printf(" <TR>"); for (m=0; m<3; m++) { printf("<TD>"); for (k=0; k < 9; k++) { if (sudoku[i*3+l][j*3+m] & 1<<k)
printf("%d", k+1);
}
printf("</TD>");
}
printf("</TR>\n");
}
printf(" </TABLE></TD>\n");
}
printf(" </TR>\n");
}
printf("</TABLE>");
}
int doRow () {
int count=0, new_value, row_value, i, j;
for (i=0; i<9; i++) {
row_value=0x1ff;
for (j=0; j<9; j++)
row_value&=~ifOne(sudoku[i][j]);
for (j=0; j<9; j++) {
new_value=sudoku[i][j] & row_value;
if (new_value && (new_value != sudoku[i][j]) ) {
count++;
sudoku[i][j] = new_value;
}
}
}
return count;
}
int doCol () {
int count=0, new_value, col_value, i, j;
for (i=0; i<9; i++) {
col_value=0x1ff;
for (j=0; j<9; j++)
col_value&=~ifOne(sudoku[j][i]);
for (j=0; j<9; j++) {
new_value=sudoku[j][i] & col_value;
if (new_value && (new_value != sudoku[j][i]) ) {
count++;
sudoku[j][i] = new_value;
}
}
}
return count;
}
int doCube () {
int count=0, new_value, cube_value, i, j, l, m;
for (i=0; i<3; i++)
for (j=0; j<3; j++) {
cube_value=0x1ff;
for (l=0; l<3; l++)
for (m=0; m<3; m++)
cube_value&=~ifOne(sudoku[i*3+l][j*3+m]);
for (l=0; l<3; l++)
for (m=0; m<3; m++) {
new_value=sudoku[i*3+l][j*3+m] & cube_value;
if (new_value && (new_value != sudoku[i*3+l][j*3+m]) ) {
count++;
sudoku[i*3+l][j*3+m] = new_value;
}
}
}
return count;
}
#define FALSE -1
#define TRUE 1
#define INCOMPLETE 0
int validCube () {
int i, j, l, m, r, c;
int pigeon;
int solved=TRUE;
//check horizontal
for (i=0; i<9; i++) {
pigeon=0;
for (j=0; j<9; j++)
if (ifOne(sudoku[i][j])) {
if (pigeon & sudoku[i][j]) return FALSE;
pigeon |= sudoku[i][j];
} else {
solved=INCOMPLETE;
}
}
//check vertical
for (i=0; i<9; i++) {
pigeon=0;
for (j=0; j<9; j++)
if (ifOne(sudoku[j][i])) {
if (pigeon & sudoku[j][i]) return FALSE;
pigeon |= sudoku[j][i];
}
else {
solved=INCOMPLETE;
}
}
//check cube
for (i=0; i<3; i++)
for (j=0; j<3; j++) {
pigeon=0;
r=j*3; c=i*3;
for (l=0; l<3; l++)
for (m=0; m<3; m++)
if (ifOne(sudoku[r+l][c+m])) {
if (pigeon & sudoku[r+l][c+m]) return FALSE;
pigeon |= sudoku[r+l][c+m];
}
else {
solved=INCOMPLETE;
}
}
return solved;
}
int solveSudoku(int position ) {
int status, i, k;
short oldCube[9][9];
for (i=position; i < 81; i++) {
while ( doCube() + doRow() + doCol() );
status = validCube() ;
if ((status == TRUE) || (status == FALSE))
return status;
if ((status == INCOMPLETE) && !ifOne(sudoku[i/9][i%9]) ) {
memcpy( &oldCube, &sudoku, sizeof(short) * 81) ;
for (k=0; k < 9; k++) {
if ( sudoku[i/9][i%9] & (1<<k) ) {
sudoku[i/9][i%9] = 1 << k ;
if (solveSudoku(i+1) == TRUE ) {
/* return TRUE; */
/* Or look for entire set of solutions */
if (cubeSolutions < 10) {
cubeValues[cubeSolutions] = malloc ( sizeof(short) * 81 ) ;
memcpy( cubeValues[cubeSolutions], &sudoku, sizeof(short) * 81) ;
}
cubeSolutions++;
if ((cubeSolutions & 0x3ffff) == 0x3ffff ) {
printf ("cubeSolutions = %llx\n", cubeSolutions+1 );
}
//if ( cubeSolutions > 10 )
// return TRUE;
}
memcpy( &sudoku, &oldCube, sizeof(short) * 81) ;
}
if (k==8)
return FALSE;
}
}
}
return FALSE;
}
int main ( int argc, char** argv) {
int i;
if (argc != 2) {
printf("Error: number of arguments on command line is incorrect\n");
exit (-12);
}
init_sudoku();
set_sudoku(argv[1]);
printf("[----------------------- Input Data ------------------------]\n\n");
print_sudoku(1);
solveSudoku(0);
if ((validCube()==1) && !cubeSolutions) {
// If sudoku is effectively already solved, cubeSolutions will not be set
printf ("\n This is a trivial sudoku. \n\n");
print_sudoku(1);
}
if (!cubeSolutions && validCube()!=1)
printf("Not Solvable\n");
if (cubeSolutions > 1) {
if (cubeSolutions >= 10)
printf("10+ Solutions, returning first 10 (%lld) [%llx] \n", cubeSolutions, cubeSolutions);
else
printf("%llx Solutions. \n", cubeSolutions);
}
for (i=0; (i < cubeSolutions) && (i < 10); i++) {
memcpy ( &sudoku, cubeValues[i], sizeof(short) * 81 );
printf("[----------------------- Solution %2.2d ------------------------]\n\n", i+1);
print_sudoku(0);
//print_HTML_sudoku();
}
return 0;
}
For one, since backtracking is a depth-first search it is not directly parallelizable, since any newly computed result cannot be used be directly used by another thread. Instead, you must divide the problem early, i.e. thread #1 starts with the first combination for a node in the backtracking graph, and proceeds to search the rest of that subgraph. Thread #2 starts with the second possible combination at the first and so forth. In short, for n threads find the n possible combinations on the top level of the search space (do not "forward-track"), then assign these n starting points to n threads.
However I think the idea is fundamentally flawed: Many sudoku permutations are solved in a matter of a couple thousands of forward+backtracking steps, and are solved within milliseconds on a single thread. This is in fact so fast that even the small coordination required for a few threads (assume that n threads reduce computation time to 1/n of original time) on a multi-core/multi-CPU is not negligible compared to the total running time, thus it is not by any chance a more efficient solution.
Are you sure you want to do that? Like, what problem are you trying to solve? If you want to use all cores, use threads. If you want a fast sudoku solver, I can give you one I wrote, see output below. If you want to make work for yourself, go ahead and use GCD ;).
Update:
I don't think GCD is bad, it just isn't terribly relevant to the task of solving sudoku. GCD is a technology to tie GUI events to code. Essentially, GCD solves two problems, a Quirk in how the MacOS X updates windows, and, it provides an improved method (as compared to threads) of tying code to GUI events.
It doesn't apply to this problem because Sudoku can be solved significantly faster than a person can think (in my humble opinion). That being said, if your goal was to solve Sudoku faster, you would want to use threads, because you would want to directly use more than one processor.
[bear#bear scripts]$ time ./a.out ..1..4.......6.3.5...9.....8.....7.3.......285...7.6..3...8...6..92......4...1...
[----------------------- Input Data ------------------------]
*,*,1 *,*,4 *,*,*
*,*,* *,6,* 3,*,5
*,*,* 9,*,* *,*,*
8,*,* *,*,* 7,*,3
*,*,* *,*,* *,2,8
5,*,* *,7,* 6,*,*
3,*,* *,8,* *,*,6
*,*,9 2,*,* *,*,*
*,4,* *,*,1 *,*,*
[----------------------- Solution 01 ------------------------]
7,6,1 3,5,4 2,8,9
2,9,8 1,6,7 3,4,5
4,5,3 9,2,8 1,6,7
8,1,2 6,4,9 7,5,3
9,7,6 5,1,3 4,2,8
5,3,4 8,7,2 6,9,1
3,2,7 4,8,5 9,1,6
1,8,9 2,3,6 5,7,4
6,4,5 7,9,1 8,3,2
real 0m0.044s
user 0m0.041s
sys 0m0.001s

Resources