C Array loop through - c

Instead of looping through each element of an array is it possible to loop through only elements which have assignments?
In the following example I would like to loop through only three elements instead of looping through each element in the array. What are my options ? I hate to loop through thousands of elements when only handful from them are assigned based on certain logic.
main()
{
int i, intArray[10000];
intArray[334] = 30;
intArray[563] = 50;
intArray[989] = 90;
for (i = 0; i < 10000; i++)
{
printf("%d\n", intArray[i]);
}
}
Thank you for reading the post. Sorry if it a re-post. I would not find similar question in the forum.

Only indirectly:
#include <stdio.h>
int main(void)
{
int i, intArray[10000];
int active[10000];
int n_active = 0;
intArray[334] = 30;
active[n_active++] = 334;
intArray[563] = 50;
active[n_active++] = 563;
intArray[989] = 90;
active[n_active++] = 989;
for (i = 0; i < n_active; i++)
printf("%d\n", intArray[active[i]]);
return 0;
}
Or, more succinctly but not more clearly:
#include <stdio.h>
int main(void)
{
int i, intArray[10000];
int active[10000];
int n_active = 0;
intArray[active[n_active++]=334] = 30;
intArray[active[n_active++]=563] = 50;
intArray[active[n_active++]=989] = 90;
for (i = 0; i < n_active; i++)
printf("%d\n", intArray[active[i]]);
return 0;
}
Both of these programs will suffer if there's more than one assignment to the same index (that index will be stored in the active array twice). As it stands, it also doesn't check for overflow of the active array (but that shouldn't be a problem; the hypothesis is that only a few of the rows are populated), and the indexes are stored in the order that they're presented — not in key order. All these defects can be fixed, but take more code (it would probably need to be a function or two).

You can do something like this
# include <stdio.h>
int totalElements = 0;
struct
{
int index, data;
} Data[10000];
void addElement(int index, int data)
{
Data[totalElements].data = data;
Data[totalElements++].index = index;
}
main()
{
int i;
addElement(334, 30);
addElement(563, 50);
addElement(989, 90);
for (i = 0; i < totalElements; i++)
{
printf("%d %d\n", Data[i].data, Data[i].index);
}
}
Output
30 334
50 563
90 989
This also suffers the same limitations Jonathan Leffler mentioned.
EDIT
# include <stdio.h>
int totalElements = 0;
struct
{
int index, currentElement = 0, data[100];
} Data[10000];
void addElement(int index, int data)
{
int i;
for (i = 0; i < totalElements; i++)
{
if (Data[i].index == index)
{
Data[i].data[Data[i].currentElement++] = data;
return;
}
}
Data[totalElements].data[Data[totalElements].currentElement++] = data;
Data[totalElements++].index = index;
}
main()
{
int i, j;
addElement(334, 30);
addElement(334, 40);
addElement(563, 50);
addElement(563, 60);
addElement(989, 80);
addElement(989, 90);
for (i = 0; i < totalElements; i++)
{
for (j = 0; j < Data[i].currentElement; j++)
{
printf("%d %d\n", Data[i].index, Data[i].data[j]);
}
}
}
Output
334 30
334 40
563 50
563 60
989 80
989 90
Using this idea you can overcome the limitations mentioned by Jonathan Leffler.

Perhaps you could use a different data structure, like a linked list. Each node in the list could have two int values, one could be the index and the other the value. The linked list would then only contain indicies which have been assigned (and you could also have value==0, if that is somehow different to the normal, unassigned index).
The other alternative would be to use something like a Dictionary structure. There are probably Dictionary implementations for C - I would say though, if C++ is available maybe you should use it instead (unless you are specifically trying to learn or are constrained to C) - C++ has many data types available straight out of the box.

Related

How to initialize a field in a struct from another struct? C

So im new to C programming and my assignment is to write a function(Max_way) that prints the driver who had the total of longest trips.
im using these 2 structs:
#define LEN 8
typedef struct
{
unsigned ID;
char name[LEN];
}Driver;
typedef struct
{
unsigned T_id;
char T_origin[LEN];
char T_dest[LEN];
unsigned T_way;
}Trip;
and a function to determine the total trips of a certain driver:
int Driver_way(Trip trips[], int size, unsigned id)
{
int km=0;
for (int i = 0; i < size; i++)
{
if (id == trips[i].T_id)
{
km = km + trips[i].T_way;
}
}
return km;
}
but when im trying to print the details of a specific driver from an array of drivers, i receive the correct ID, the correct distance of km, but the driver's name is not copied properly and i get garbage string containing 1 character instead of 8.
i've also tried strcpy(max_driver.name,driver[i].name) with same result.
void Max_way(Trip trips[], int size_of_trips, Driver drivers[], int size_of_drivers)
{
int *km;
int max = 0;
Driver max_driver;
km = (int*)malloc(sizeof(int) * (sizeof(drivers) / sizeof(Driver)));
for (int i = 0; i < size_of_drivers; i++)
{
km[i] = Driver_way(trips, sizeof(trips), drivers[i].ID);
for (int j = 1; j < size_of_drivers; j++)
{
if (km[j] > km[j - 1])
{
max = km[j];
max_driver.ID = drivers[i].ID;
max_driver.name = drivers[i].name;
}
}
}
printf("The driver who drove the most is:\n%d\n%s\n%d km\n", max_driver.ID, max_driver.name, max);
}
any idea why this is happening?
Note that one cannot copy a string using a simple assignment operator; you must use strcpy (or similar) as follows:
if (km[j] > km[j - 1]) {
max = km[j];
max_driver.ID = drivers[i].ID;
strcpy(max_driver.name,drivers[i].name);
}
Also note that since you were using ==, this was not even a simple assignment, put a comparison. Changing to == likely fixed a compile-time error, but it did NOT give you what you want.

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

Changing the contents of an array in a recursive function

I am having trouble understanding something regarding recursion and arrays.
basically, what the program does is to check what is the maximum weights of items that can be placed in two boxes. I know it's far from perfect as it is right now, but this is not the point.
Generally everything is working properly, however, now I decided that I want to see the contents of each box when the weight is maximal. For this purpose I tried using arr1 and arr2.
I don't understand why I get different results for arr1 and arr2 (the first options gives me what I want, the second does not).
This is the program:
#define N 5
int help(int items[N][2], int box1[N], int box2[N], int rules[N][N],
int optimal,int current_weight,int item,int arr1[],int arr2[])
{
if (item == N)
{
if(current_weight>optimal) //This is the first option
{
memcpy(arr1,box1,sizeof(int)*N);
memcpy(arr2,box2,sizeof(int)*N);
}
return current_weight;
}
int k = items[item][1]; int sol;
for (int i = 0; i <= k; i++)
{
for (int j = 0; i+j <= k; j++)
{
box1[item] += i; box2[item] += j;
if (islegal(items, box1, box2, rules))
{
sol = help(items, box1, box2, rules, optimal,
current_weight + (i + j)*items[item][0],item+1,arr1,arr2);
if (sol > optimal)
{
optimal = sol;
memcpy(arr1,box1,sizeof(int)*N); //This is the second option
memcpy(arr2,box2,sizeof(int)*N);
}
}
box1[item] -= i; box2[item] -= j;
}
}
return optimal;
}
int insert(int items[N][2], int rules[N][N])
{
int box1[N] = { 0 }; int arr1[N] = { 0 };
int box2[N] = { 0 }; int arr2[N] = { 0 };
int optimal = 0;
int x = help(items, box1, box2, rules,0, 0,0,arr1,arr2);
print(arr1, N);
print(arr2, N);
return x;
}
Can anyone explain what causes the difference? Why the first option is correct and the second is not? I couldn't figure it out by my own.
Thanks a lot.
This doesn't work because when you pass box1 and box2 to help, they are mutated by help. It's pretty obvious from the algorithm that you want them to not be mutated. So, we can do as follows:
int help(int items[N][2], int box1in[N], int box2in[N], int rules[N][N],
int optimal,int current_weight,int item,int arr1[],int arr2[])
{
int box1[N];
int box2[N];
memcpy(box1, box1in, sizeof(int)*N);
memcpy(box2, box2in, sizeof(int)*N);
Your algorithm may still have problems but that problem is now removed.

Name variables dynamically

I am creating n threads. I would like to create n variables b1,b2,b3,.,bi,..bn.
How can I do this in C? I mean to choose the name of the global variable according to the number of the thread.
thanks
Taken from NapoleonBlownapart's comment to the OP: "You can't. Variable names only exist at compile time, while threads only exist at runtime."
Use an array, with as much elements as you have threads. Then use the thread's number as index to the arrary
See some pseudo code below:
#define THREAD_MAXIMUM (42)
int b[THREAD_MAXIMUM];
thread_func(void * pv)
{
size_t i = (size_t) pv;
int bi = b[i];
...
}
int main()
{
...
for(size_t i = 0; i < THREAD_MAXIMUM; ++i)
{
b[i] = some thread specific number;
create-thread(thread_func, i) /* create thread and pass index to array element);
}
...
}
You can try with arrays or vectors(in C++). I would have preferred coding in C++ and use vector instead of C and array.
Simple implementation with array can be as follows -
#define MAX_THREAD(100)
int var[MAX_THREAD]
ThreadImpl(Params)
{
int i = (int) Params;
int vari = var[i];
}
int main()
{
for(int i = 0; i < MAX_THREAD; ++i)
{
var[i] = val; (val can be ThreadID or other value as per requirement)
pthread_create(ThreadImpl, ... other params);
}
return 0;
}

increment in a loop and keeping state

gcc 4.4.4 c89
I have the following code and 2 structures that have to be filled.
I have 3 functions that will fill the handles for each of the devices.
However, the device_type structure will need to increment from where the last function finished.
For example:
load_resources() starts at 0 and finishes at 9
dev_types starts at 0 and finishes at 9
load_networks() starts at 0 and finishes at 9
dev_types starts at 10 and finishes at 19
load_controls() starts at 0 and finishes at 9
dev_types starts at 20 and finishes at 29
However, as I don't want to use a static or global variable is there any way I can increment a
value for this. So it will start where the last function finished.
Many thanks for any suggestions,
#define NUMBER_OF_DEVICES 10
#define NUMBER_OF_TYPES 3 /* resources
networks
controls */
int events(int evt);
int load_resources();
int load_networks();
int load_controls();
static struct device_table {
int resource_handle;
int network_handle;
int control_handle;
} dev_tbl[NUMBER_OF_DEVICES];
struct device_types {
size_t id;
int dev_handle;
int dev_type;
}dev_types[NUMBER_OF_DEVICES * NUMBER_OF_TYPES];
enum dev_name_types {RESOURCE, NETWORK, CONTROL};
/* Simulates the API calls, by returning a dummy handle */
int get_resources();
int get_networks();
int get_controls();
int main(void)
{
srand(time(NULL));
load_resources();
load_networks();
load_controls();
return 0;
}
int load_resources()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].resource_handle = get_resources();
printf("dev_tbl[i].resource_handle [ %d ]\n", dev_tbl[i].resource_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].resource_handle;
dev_types[i].dev_type = RESOURCE;
}
}
int load_networks()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].network_handle = get_networks();
printf("dev_tbl[i].network_handle [ %d ]\n", dev_tbl[i].network_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].network_handle;
dev_types[i].dev_type = NETWORK;
}
}
int load_controls()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].control_handle = get_controls();
printf("dev_tbl[i].control_handle [ %d ]\n", dev_tbl[i].control_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].control_handle;
dev_types[i].dev_type = CONTROL;
}
}
Why not change the prototypes to something like:
void load_resources(int*)
(they're not actually returning anything) then, in your main code, have:
int base = 0;
load_resources (&base);
load_networks (&base);
load_controls (&base);
Each function is then responsible for using and updating *base like this:
void load_resources (int *pBase) {
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++, (*pBase)++) { // <-- see here!
dev_tbl[i].resource_handle = get_resources();
printf("dev_tbl[i].resource_handle [ %d ]\n", dev_tbl[i].resource_handle);
dev_types[*pBase].id = i;
dev_types[*pBase].dev_handle = dev_tbl[i].resource_handle;
dev_types[*pBase].dev_type = RESOURCE;
}
}
One option is to have each of your functions take the base index as a parameter, and returning the first available index:
int index = 0;
index = load_resources(index);
index = load_network(index);
// and so on
With this yout functions would look something like this:
int load_resources(int base_index)
{
size_t i = 0;
size_t index;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
index = base_index + i;
dev_tbl[index].resource_handle = get_resources();
//
}
return index + 1;
}
By the way, your functions do have int return types, but do not return anything.
Hold a pointer or index variable within the structure itself. It's an indicator for how far the structure has been filled up generally.
There are only two ways to persist data from one scope to the next - on the stack and on the heap. Since you have already ruled out any global variables here, that would require you to use stack variables, by passing in a parameter and returning a value, or passing in a pointer to a parameter.

Resources