I have to use quick select to sort and write the first N elements of an array and write them on a text.
The problem is with the input file and the quantity of data I try to read from it.
I use a constant, N, to define the max quantity of number I want to read from the file, but so far it only reads and sorts up to 194 elements from the file. I should be able to do it with 10 million, however.
Here's the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#define N 194
float qselect(float *array,int ini, int fin, int k){
int i;
int st = ini;
float tmp;
//finding a pivot
for (i = 0; i < fin - 1; i++) {
if (array[i] < array[fin-1]) {
tmp = array[st];
array[st] = array[i];
array[i] = tmp;
st++;
}
}
//exchanging the pivot with the last element of the array
tmp = array[fin-1];
array[fin-1] = array[st];
array[st] = tmp;
//veryfing the pivot
if (k == st)
return array[st];
else if (st>k)
return qselect(array,ini,st,k);//search on the left
else
return qselect(array,ini+st,fin,k);//search on the right
}
int main(void)
{
FILE *input;
FILE *output;
int range;
//opening the files
input = fopen("numeros.txt","r");
output = fopen("out.txt","w");
printf("Select your N : ");
scanf("%d",&range);
float *array_x;
array_x = malloc(sizeof(float)*N);
float num;
int size=0;
for(int f=0;f<N; f++){
fscanf(input,"%f",&array_x[size]);
size++;
}
int i;
for (i = 0; i < range; i++) {
fprintf(output,"%f ", qselect(array_x,0, size, i));
}
fclose(input);
fclose(output);
free(array_x);
return 0;
}
If I try to define N=195 or more, the code doesn't work.
Related
I have to print the pascal's triangle given a certain number of levels desired. The max levels that will be asked for is 28. I am able to print the some of the rows correctly but then it starts printing negative numbers in the rest of my rows. I can't figure out why, help would be much appreciated!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void printTriangle() {
int numLevels;
printf("Please enter how many levels of Pascal's Triangle you would like to see: ");
scanf("%d", &numLevels);
char pascalTriangle[28][28];
for (int k = 1; k <= numLevels; ++k) {
for (int i = 0; i < k; ++i) {
int val = (i == 0) || (i == k - 1) ? 1 : (pascalTriangle[k-1][i-1] + pascalTriangle[k-1][i]);
pascalTriangle[k][i] = val;
printf(" %d", val);
}
printf("\n");
}
}
int main() {
printTriangle();
}
Change char pascalTriangle[28][28]; to int pascalTriangle[28][28];. You're going over the max char value so it goes to negative.
There is no "array" type, only a collection of pointers. You can also change char to short, long, etc.
Also, change k <= numLevels to k < numLevels. This prevents the segmentation fault. To fix the logic, you have to change for(int i = 0; to for(int i = -1;
The fixed code is:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void printTriangle() {
int numLevels;
printf("Please enter how many levels of Pascal's Triangle you would like to see: ");
scanf("%d", &numLevels);
long long pascalTriangle[28][28];
for (int k = 0; k < numLevels; ++k) {
for (int i = -1; i < k; ++i) {
long long val = (i == 0) || (i == k - 1) ? 1 : (pascalTriangle[k-1][i-1] + pascalTriangle[k-1][i]);
pascalTriangle[k][i] = val;
printf(" %lld", val);
}
printf("\n");
}
}
int main() {
printTriangle();
}
I am writing a C program that should sort floats (increasingly). The values are saved in a file and then after the sort, the values are saved into the same file. I am using library functions to read and write. I am using radixsort to sort the floats.
This is the code I currently have. Rather than the array being populated with values from the file that I am reading, it is storing 0.000000 for every index. I am not sure where I am going wrong in my implementation.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
void swap(float *a, float *b, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
float tmp = a[i];
a[i] = b[i];
b[i] = tmp;
}
}
void radixSort(float array[], size_t count)
{
int numZeroes=0;
float tempArr1[count];
float * tempArr2 = tempArr1;
for (uint32_t radix=1;radix;radix<<=1){
uint32_t * intArray = (uint32_t *)array;
int count0=0;
int count1=0;
numZeroes=0;
for (int j=0; j<count; ++j)
numZeroes += !(intArray[j]&radix);
count1=numZeroes;
for (int j=0; j < count; ++j)
if (intArray[j]&radix){
tempArr2[count1]=array[j];
++count1;
}
else{
tempArr2[count0]=array[j];
++count0;
}
swap(tempArr2,array,count);
}
if (numZeroes<count){
memcpy( tempArr2+(count-numZeroes), array, numZeroes*sizeof(float));
for (int d=0,j=count-1;j>=numZeroes;j--,d++)
tempArr2[d]=array[j];
memcpy( array, tempArr2, count * sizeof(float));
}
}
int main(int argc, char *argv[]) {
FILE *fd, *writeFile;
int i = 0;
float number;
int elementnum = 0;
struct stat st;
int fd2;
fd=fopen(argv[1], "r");
fd2 = fileno(fd);
if(fd==NULL){
printf("Error opening file\n");
}
fstat(fd2, &st);
off_t size = st.st_size;
for(int j = 0; j < size/4; j++){
elementnum++;
}
float array[elementnum];
while(fscanf(fd, "%f", &number)==1) {
array[i] = number;
i++;
}
radixSort(array,elementnum);
for(int j = 0; j < elementnum; j++){
printf("%f\n", array[j]);
}
fclose(fd);
writeFile=fopen("argv[1]", "w");
for(int j = 0; j < elementnum; j++){
fprintf(writeFile, "%f\n", array[j]);
}
fclose(writeFile);
return 0;
}
At least these issues:
Code is assuming the size of the text file divided by 4 is the number of float. This is risky and error prone. #agus
Instead of fstat(fd2, &st);, count them
size_t elementnum = 0;
while(fscanf(fd, "%f", &number)==1) {
elementnum++;
}
rewind(fd);
float array[elementnum];
for (i=0; i < elementnum; i++) {
if (fscanf(fd, "%f", &number) != 1) {
puts("We have trouble reading the same on the 2nd pass");
exit(1);
}
array[i] = number;
}
radixSort(array, elementnum);
/ 4 might make sense with a binary file and using fread() to read float.
it is storing 0.000000 for every index
Writing float with "%f" is uninformative with small values. Better to use "%e" or "%g".
#include <float.h>
// fprintf(writeFile, "%f\n", array[j]);
fprintf(writeFile, "%g\n", array[j]);
// or better
fprintf(writeFile, "%.*g\n", FLT_DECIMAL_DIG, array[j]);
Command:
the program reads the file and saves it in memory, treating each line as a subtitle (Note: to simplify the program, we can assume that we know the limit for the length of the line (say 1023 characters) and we know the limit for the number of lines (say 2048), but we expect that the lengths of individual lines can vary greatly, so we allocate the memory for each line dynamically during reading, writing the addresses of subsequent subtitles in the table)
I have a code that reads one line, but I don't know how to change it so that the program reads all the lines into different arrays and then reads the indicators into them into the next array
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLINE 1023
#define ROW 32
int main()
{
FILE *fp;
char *array;
size_t csize = ROW;
size_t cpos = 0;
int ch;
fp = fopen("plik.txt", "r");
array = malloc(ROW);
while((ch = fgetc(fp))!='\n'&& ch!='\r')
{
array[cpos++] = ch;
if(cpos == csize)
{
csize += ROW;
array = realloc(array, csize);
}
}
array[cpos] = 0;
fclose(fp);
free(array);
return 0;
}
Here I have example how you can initialize dynamicaly two dimentional array of floats.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int x, y;
printf("Enter x\n");
scanf("%d", &x);
printf("Enter y\n");
scanf("%d", &y);
float** matrix = (float**)malloc(x * sizeof(float));
for (int i = 0; i < x; i++)
{
matrix[i] = (float*)malloc(y * sizeof(float));
}
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
int value = rand()%10000;
matrix[i][j] = (float)value / 100;
printf("%.2f ", matrix[i][j]);
}
printf("\n");
}
free(matrix);
}
Play a little bit with this code. You shouldn't have any problems to initialize every line with different length.
I need in c code that generates two numbers in horizontally...so that i can get token numbers for my login system.
I need that i get this:
token=0.152644,0.429187
so in example i have token= and random generated numbers that have at beginning 0. and then 6 random generated numbers separated with , sign.
How to get get this in C?
I have try this code but it does not give me what i want_
#include <stdio.h>
#include <string.h>
typedef
union
{
char tmp[sizeof(unsigned long long)];
unsigned long long myll;
} ll_t;
unsigned long long llrand(void)
{
FILE *in=fopen("/dev/urandom", "r");
ll_t ll_u;
fread(ll_u.tmp, sizeof(ll_u.tmp), 1, in);
fclose(in);
return ll_u.myll;
}
int main()
{
char tmp1[64]={0x0};
char working[64]={0x0};
int i=0;
for(i=0; i< 1; i++)
{
while(strlen(tmp1) < 6)
{
sprintf(working, "%lu", llrand() );
strcat(tmp1, working);
}
tmp1[6]=0x0;
printf("%s\n", tmp1);
*tmp1=0x0;
}
return 0;
}
From output i get this:
747563
102595
Can code be simple and short?
You can use rand() function:
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
int randomNumber(int min, int max)
{
/* generate secret number between min and max: */
int res = rand() % (max-min+1) + min;
return res;
}
int main()
{
int i = 0;
srand (time(NULL));
for (i=0; i<100; i++)
printf("%d ", randomNumber(10, 1000000));
return 0;
}
That is full detail for rand():
http://www.cplusplus.com/reference/cstdlib/rand/
Here is the code that is working perfect:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n1, n2;
time_t t;
srand((unsigned) time(&t));
n1 = rand() % 1000000 + 1;
n2 = rand() % 1000000 + 1;
printf("token=0.%d,0.%d\n", n1, n2);
return 0;
}
And output is:
token=0.289384,0.930887
A propose a different approach. Instead of generating 2 numbers and format them into the output string, generate 12 different digits and put them directly in place.
srand(time(0));
char output[] = "taken=0.XXXXXX,0.YYYYYY";
for (int n = 0; n < 2; n++) {
for (int k = 0; k < 6; k++) {
output[9 * n + 8 + k] = rand() % 10 + '0';
// you might want to write a function that deals with rand() bias
}
}
puts(output);
I updated my main and sequetialSearch and now it crashes when it runs. It compiles okay, but then crashes.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include "percentage.h"
#include "sequentialSearch.h"
#define searchAmount 100
int main(int argc, char *argv[])
{
int numbers[100];
int searches[searchAmount];
int testAmounts[searchAmount];
int i;
int where;
int searchSuccess;
int searchUnsuccess;
int percent;
int looker;
int sum;
int average;
srand(time(NULL));
for (i = 0; i < 100; i++){
numbers[i] = rand() % 200;
}
for (i = 0; i < searchAmount; i++){
searches[i] = rand() % 200;
}
searchUnsuccess = 0;
searchSuccess = 0;
sum = 0;
for(i = 0; i < searchAmount; i++){
if(seqSearch(numbers, 100, searches[i], &where, &looker)){
searchSuccess++;
testAmounts[i] = looker;
}else{
searchUnsuccess++;
testAmounts[i] = looker;
}
}
for(i = 0; i < searchAmount; i++){
sum = sum + testAmounts[i];
}
average = sum / searchAmount;
percent = percentRate(searchSuccess, searchAmount);
printf("Total number of searches: %d\n", searchAmount);
printf("Total successful searches: %d\n", searchSuccess);
printf("Success Rate: %d%%\n", percent);
printf("Total number of tests ran: %d\n", average);
system("PAUSE");
return 0;
}
sequentialSearch.h
bool seqSearch (int list[], int last, int target, int* locn, int* looker){
*looker = 0;
while(*looker < last && target != list[*looker]){
*looker++;
}
*locn = *looker;
return(target == list[*looker]);
}
Pass looker in by reference, so that you can access its value from the caller.
int looker;
...
for(i = 0; i < searchAmount; i++){
if(seqSearch(numbers, 100, searches[i], &where, &looker)){
searches[i] += looker;
searchSuccess++;
}else{
searchUnsuccess++;
}
}
bool seqSearch (int list[], int last, int target, int* locn, int *looker){
*looker = 0;
while(*looker < last && target != list[*looker]){
(*looker)++;
}
*locn = *looker;
return(target == list[*looker]);
}
By the way, you may wish to reconsider defining functions in your header file; this could cause problems with duplicate symbol when linking if you have more than one c file including this file.
Why not just pass looker in as an int*, use it essentially as you have been, look at the value after seqSearch(...) returns, and add it to a running total back in main()?
One problem is that the increment of looker in seqSearch is incrementing the pointer rather than the value. It should probably be:
(*looker)++;