Counting number of strings in hash table - c

So, I am trying to count the number of strings present in my hash table. For some reason, this function always returns 0. I have tried re-writing it a couple of times in slightly different ways to find an error in the logic, but, as far as I know, this function should output the number of entries in the table. I would really appreciate some help, as this has become very frustrating! Thanks!
/* htbl_n_entries : htbl* -> unsigned int */
/* return the number of entries in all buckets */
unsigned int htbl_n_entries(htbl *t){
int i;
int nbucks = t->n_buckets;
sll**bucks= t->buckets;
unsigned int sum = 0;
for (i = 0; i < nbucks; ++i)
{
while(bucks[i] != NULL){
sum++;
bucks[i] = bucks[i]->next;
}
}
return sum;
}

The while in your code will set to NULL each bucks[i]. Try:
sll**bucks= t->buckets;
unsigned int sum = 0;
for (i = 0; i < nbucks; ++i)
{
sll*bucks_= bucks[i];
while(bucks_ != NULL){
sum++;
bucks_ = bucks_->next;
}
}
This is just one error, but do not explain why return 0. It correctly count the first time, but any other time will be 0. My gess is that you have simmilar error in other functions and at this point your table is allready broken.

Related

How to find the minimum number of coins needed for a given target amount(different from existing ones)

This is a classic question, where a list of coin amounts are given in coins[], len = length of coins[] array, and we try to find minimum amount of coins needed to get the target.
The coins array is sorted in ascending order
NOTE: I am trying to optimize the efficiency. Obviously I can run a for loop through the coins array and add the target%coins[i] together, but this will be erroneous when I have for example coins[] = {1,3,4} and target = 6, the for loop method would give 3, which is 1,1,4, but the optimal solution is 2, which is 3,3.
I haven't learned matrices and multi-dimensional array yet, are there ways to do this problem without them? I wrote a function, but it seems to be running in an infinity loop.
int find_min(const int coins[], int len, int target) {
int i;
int min = target;
int curr;
for (i = 0; i < len; i++) {
if (target == 0) {
return 0;
}
if (coins[i] <= target) {
curr = 1 + find_min(coins, len, target - coins[i]);
if (curr < min) {
min = curr;
}
}
}
return min;
}
I can suggest you this reading,
https://www.geeksforgeeks.org/generate-a-combination-of-minimum-coins-that-results-to-a-given-value/
the only thing is that there is no C version of the code, but if really need it you can do the porting by yourself.
Since no one gives a good answer, and that I figured it out myself. I might as well post an answer.
I add an array called lp, which is initialized in main,
int lp[4096];
int i;
for (i = 0; i <= COINS_MAX_TARGET; i++) {
lp[i] = -1;
}
every index of lp is equal to -1.
int find_min(int tar, const int coins[], int len, int lp[])
{
// Base case
if (tar == 0) {
lp[0] = 0;
return 0;
}
if (lp[tar] != -1) {
return lp[tar];
}
// Initialize result
int result = COINS_MAX_TARGET;
// Try every coin that is smaller than tar
for (int i = 0; i < len; i++) {
if (coins[i] <= tar) {
int x = find_min(tar - coins[i], coins, len, lp);
if (x != COINS_MAX_TARGET)
result = ((result > (1 + x)) ? (1+x) : result);
}
}
lp[tar] = result;
return result;
}

Segmentation Fault when returning integer

I recently joined Stackoverflow community because I had to ask this question. I've been searching for possible explanations and solutions on the website but so far nothing enlightened me as I wanted. My error is probably caused by a very specific line of code. I'm trying to create a function that reads an array of struct votes, (struct contains integer member number, char *category, char *nominee) and copies all the votes that contain the same number and category to another array of struct. Basically to show all the repeated votes.
typedef struct
{
int member;
char *categ;
char *nom;
}Vote
Vote vote(int member, char *categ, char *nom)
{
Vote result;
result.member = member;
result.categ = categ;
result.nom = nom;
return result;
}
int votes_count(Vote *v, int n, Vote *v1)
{
int result = 0;
int *index = malloc(sizeof(int) * 1000);
int a = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (a == 0 && v[i].member == v[j].member && strcmp(v[i].categ, v[j].categ) == 0)
{
v1[result++] = vote(v[j].member, str_dup(v[j].categ), str_dup(v[j].nom));
index[a++] = j;
}
for (int b = 0; b < a; ++b)
{
if( a > 0 && v[i].member == v[j].member && strcmp(v[i].categ, v[j].categ) == 0 && j != index[b])
{
v1[result++] = voto(v[j].member, str_dup(v[j].categ), str_dup(v[j].nom));
index[a++] = j;
}
}
}
}
return result;
}
Afterwads, it returns the number of elements of new array that contains all repetitions. I want to use an array of ints to save all line indexes so that the function doesn't read and copy the lines it already accounted.
Sorry if the code is hard to understand, if needed I can edit to be more understandable. Thanks for any answears.
P.S: I'm portuguese, sorry in advance for grammar mistakes
if your only intention is to harvest the duplicates, you only need to compare to the elements that came before an element
you don't need the index[] array
For simplicity, I used two integer arrays, you should change them to your struct arrays, also change the compare function.
unsigned fetchdups(int orig[], int dups[], unsigned count)
{
unsigned this, that, ndup=0;
for (this=1; this<count; this++){
for (that=0; that<this; that++){
/* change this to your compare() */
if(orig[that] == orig[this]) break;
}
if (this == that) continue; /* no duplicate */
dups[ndup++] = this;
}
return ndup;
}

Segmentation fault (core dumped) error, in a C search function

I'm trying to write a C program to take an array of discrete positive integers and find the length of the longest increasing subsequence.
'int* a' is the array of randomly generated integers, which is of length 'int b'
call:
lis_n = answer(seq, seq_size);
function:
int answer(int* a, int b) {
if (a == NULL) {return -1;}
int i = 0;
int j = 0;
int k = 0;
//instantiate max and set it to 0
int max = 0;
//make an array storing all included numbers
int included[b];
memset(included, 0, b*sizeof(int));
//create a pointer to the index in included[] with the largest value
int indexMax = 0;
//create a pointer to the index in a[]
int indexArray = 0;
//index of a[] for max included
int maxToA = 0;
//set the first included number to the first element in a[]
included[indexMax] = a[indexArray];
//loop until break
while (1) {
if (a[indexArray] > included[indexMax]/*digit greater than last included*/) {
//include the digit
included[indexMax+1] = a[indexArray];
//increment current max pointer
indexMax++;
}
j = b - 1;
while (indexArray >= j/*pointer is at end"*/) {
if (j == (b - 1)) {
if ((indexMax+1) > max/*total is greater than current max*/) {
max = indexMax + 1;
}
}
if (a[b-1] == included[0]/*last element is in included[0], stop*/) {
return max;
} else {
//max included is set to zero
included[indexMax] = 0;
//max included pointer decreased
indexMax--;
//set array pointer to new max included
for (k=0;k<(b-1);k++) {
if (a[k] == included[indexMax]) {
indexArray = k;
}
}
//increment array pointer
indexArray++;
j--;
}
}
indexArray++;
printf("(");
for (i=0;i<b;i++) {
printf("%d,",included[i]);
}
printf(")");
}
}
I'm receiving 'Segmentation fault (core dumped)' in the terminal upon running.
Any help would be awesome.
You have declared
int indexMax = 0;
And here you use it as an array index
incuded[indexMax] = 0;
You increment and decrement it
indexMax++;
...
indexMax--;
You check its range but you don't limit it, you alter the value you compare it with
if ((indexMax+1) > max/*total is greater than current max*/) {
max = indexMax + 1;
}
You never check indexMax against b or with 0
int included[b];
So you are almost guaranteed to exceed the bounds of included[].
Some general points of advice. Make your function and variable names meaningful. Avoid making a premature exit from a function wherever possible. Avoid while(1) wherever possible. And never make assumptions about array sizes (including C "strings"). It might seem hard work putting in the overhead, but there is a payoff. The payoff is not just about catching unexpected errors, it makes you think about the code you are writing as you do it.
I've done something like this for homework before. I got help from:
https://codereview.stackexchange.com/questions/30491/maximum-subarray-problem-iterative-on-algorithm
Make sure you are not trying to index past the size of your array. What I would do would be to find out the size of array a[] (which looks like it is b) and subtract 1. Make sure you are not trying to access past the size of the array.

Arduino - Optimising existing method for iterating through an array

Is there a more efficient and cleaner way of doing what the following method is already doing?
void sendCode(prog_uint16_t inArray[], int nLimit) {
unsigned int arr[nLimit];
unsigned int c;
int index = 0;
while ((c = pgm_read_word(inArray++))) {
arr[index] = c;
index++;
}
for (int i = 0; i < nLimit; i=i+2) {
delayMicroseconds(arr[i]);
pulseIR(arr[i+1]);
}
}
This is in reference to an existing question I had answered.
Arduino - Iterate through C array efficiently
There should be no need for the local arr array variable. If you do away with that you should both save temporary stack space and speed up execution by removing the need to copy data.
void sendCode(const prog_uint16_t inArray[]) {
unsigned int c;
for (int i = 0; c = pgm_read_word(inArray++); i++) {
if (i % 2 == 0) { // Even array elements are delays
delayMicroseconds(c);
} else { // Odd array elements are pulse lengths
pulseIR(c);
}
}
}
This code assumes that the maximum integer stored in an int is greater than the maximum size of inArray (this seems reasonable as the original code essentially makes the same assumption by using an int for nLimit).

C Arrays and unbroken lists

/edit: thanks for the help so far, however I haven't got any of the solutions to take the sample input and give the sample output. My description isn't the clearest, sorry.
I have an array composed of binary data. What I want to do is determine how long each unbroken segment of 1s or 0s is.
Say I have this data:
0111010001110
In an array binaryArray which I need to translate to:
0100110
stored in nwArray where 0 represents a narrow (less than 3 digits long) and 1 represents wide (>3 digits long). I am not concerned with the binary value but with the length of each component. I'm not sure if that explanation makes sense.
This is what I have; it doesn't work, I can see why, but I can't think of a good solution.
for(x=0;x<1000;x++){
if(binaryArray[x]==binaryArray[x+1]){
count++;
if(count>=3){
nwArray[y]=1;
y++;
count=0;
}
}else{
if(barcodeArray[x]){
nwArray[y]=0;
}
}
}
Does this do it?
int count = 0;
for (x=0; x<1000;x++)
{
if (binaryArray[x] != binaryArray[x+1])
{
if (count < 3)
nwArray[y]=0;
else
nwArray[y]=1;
y++;
count = 0;
}
else
count++;
}
One problem you have is that you compare count with 3 too early. Wait until you see a change in the bitstream. Try a while loop until the bit flips then compare the count.
Modified #MikeW's answer:
int count = 0;
int nwSize = 0;
const int ilast = SIZEOF(binaryArray) - 1;
for (int i = 0; i <= ilast; ++i)
if (i == ilast || binaryArray[i] != binaryArray[i+1]) {
nwArray[nwSize++] = (count > 1); /* true for '1110'; false for '110' */
count = 0;
}
else
++count;
assert(count == 0);

Resources