Существует ли функция C, которая возвращает второму, третьему и т. Д. Экземпляру значение int? - PullRequest
0 голосов
/ 07 мая 2018

Я реализовал код, который импортирует данные из файла, содержащего 5 различных значений, одним из которых является время.Я перевел время, указанное в формате Hour.Minute.Second.Millisecond, в миллисекунды.

С этими данными я создал функцию Find, которая находит данные за заданное время.Именно здесь возникает проблема, поскольку здесь есть данные за несколько дней, и время будет повторяться несколько раз.Есть ли в библиотеке C функция, которая возвращает все экземпляры значения?Пример. arr =[2,3,4,1,2,] Я хочу, чтобы он сообщал мне, когда появятся вторые 2, возвращая 4.

Редактировать: Для большей ясности

Это функции

void Find(SortedLinkedList *list,int target,int date, char *search) {
    if(strcmp(search, "Time") == 0){
      Sate *found = findTime(list, target,date);
      printf("The Node with time:%d\n Is from the date:%d\n Contains the following:",found->Time,found->Date);
      printf("RMag:%6.3f ", found->rmag);
        printf("NSmag:%6.3f ", found->NSmag);
        printf("azmag:%6.3f ", found->azmag);
        printf("avgmag:%6.3f \n", found->avgmag);
    }

}

Sate *findTime(SortedLinkedList *list, int target,int date){
    Node *current = list->head;
    for (int i = 0; i < (list->size)+1 && current != NULL; i++) {
        if(current->data->Time == target && current->data->Date == date)
         return current->data;
    else{
      current = current->next;

    }
    }

}

Прямо сейчас, чтобы это заработало, я применил вставку date, чтобы различать время, но мне интересно, можно ли это сделать без нее.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

В стандартной библиотеке C нет итераций по типу коллекции, кроме как что-то вроде strtok(), которое будет перебирать текстовую строку с использованием предоставленного шаблона идентификации токена.

Однако есть функция bsearch(), которая выполняет поиск по отсортированному списку элементов и не совсем то, что вам нужно.

Звучит так, будто вы хотите что-то вроде следующего. Это демонстрирует реализацию алгоритма, однако я не уверен, как выглядят данные временных точек, так что это то, что вам нужно будет предоставить.

typedef unsigned long long  TimePoint;     // made up time data item

typedef  struct {
    int            bFound;
    unsigned long  ulCurOffset; // array position where item found if bFound is true.
    unsigned long  ulOffset;    // next array position to test
    unsigned long  ulCount;     // count of times found
} IteratorThing;

IteratorThing IterateFunc (IteratorThing x, TimePoint *array, size_t len, TimePoint search)
{
    x.bFound = 0;    // assume we didn't find one.
    // resuming from the current place in the array, search until we
    // find a match or we reach the end of the array.
    for ( ; x.ulOffset < len; x.ulOffset++) {
        // this is a simple comparison for equality which may need to be
        // more complex for your specific application.
        if (array[x.ulOffset] == search) {
            // we have found a match so lets update counts, etc.
            x.ulCount++;     // count of this search item found.
            x.bFound = 1;    // indicate we found one.
            x.ulCurOffset = x.ulOffset;   // remember where we found it.
            x.ulOffset++;    // point to the next array item to look at
            break;
        }
    }
    return x;
}

Это будет использоваться как в:

void main_xfun(void)
{
    TimePoint  array[] = { 1, 2, 3, 2, 3, 4, 0 };
    TimePoint  search = 2;
    size_t     len = sizeof(array) / sizeof(array[0]);

    {
        IteratorThing x = { 0 };  // define and initialize our iterator
        while ((x = IterateFunc(x, array, len, search)).bFound) {
            // do what is needed when we find a time value
            // array offset to the item is x.ulCurOffset
            // current count of times found is in x.ulCount;
            printf("   found item %d at offset %d count is %d\n", (long)array[x.ulCurOffset], x.ulCurOffset, x.ulCount);
        }
        printf(" item %d found %d time\n", (long)search, x.ulCount);
    }

    {
        IteratorThing x = { 0 };  // define and initialize our iterator
        search = 25;
        while ((x = IterateFunc(x, array, len, search)).bFound) {
            // do what is needed when we find a time value
            // array offset to the item is x.ulCurOffset
            // current count of times found is in x.ulCount;
            printf("   found item %d at offset %d count is %d\n", (long)array[x.ulCurOffset], x.ulCurOffset, x.ulCount);
        }
        printf(" item %d found %d time\n", (long)search, x.ulCount);
    }
}

производит вывод

    found item 2 at offset 1 count is 1
    found item 2 at offset 3 count is 2
 item 2 found 2 time
 item 25 found 0 time

Чтобы возобновить поиск с самого начала, просто инициализируйте структуру итератора для всех нулей.

Что было бы действительно интересно, так это предоставить указатель на функцию сравнения в интерфейсе функции IterateFunc(), которая будет вызываться для сравнения. Это было бы в соответствии с функцией bsearch(), для которой требуется указатель на функцию сравнения, но это, вероятно, излишне для ваших конкретных потребностей.

0 голосов
/ 07 мая 2018

Если вы хотите, чтобы эта гипотетическая функция работала либо с массивом целых чисел, либо с вашими индексированными по времени структурами, вам, вероятно, потребуется написать универсальную функцию.

Если вам доступны функции POSIX, вы можете использовать lfind() в качестве отправной точки для такой общей функции.

Функция lsearch() выполняет линейный поиск в таблице и возвращает указатель в таблицу для соответствующей записи. Если запись не происходит, она должна быть добавлена ​​в конце таблицы. ...

Функция lfind() должна быть эквивалентна lsearch(), за исключением того, что если запись не найдена, она не добавляется в таблицу. Вместо этого возвращается нулевой указатель.

Поскольку lfind() вернет первый экземпляр, вам нужно повторно вызвать lfind() снова после данного экземпляра, чтобы найти второй экземпляр.

void * lfind_Nth (const void *key, const void *base, size_t *nelp,
   size_t width, int (*compar)(const void *, const void *),
   int N)
{
    const char (*array)[width] = base;
    char (*p)[width] = NULL;
    size_t n = *nelp;

    while (N-- > 0) {
        p = n ? lfind(key, array, &n, width, compar) : NULL;
        if (p == NULL) break;
        n -= (p + 1) - array;
        array = p + 1;
    }

    return p;
}

Для вашего примера целочисленного массива:

int compar_int (const void *a, const void *b) {
    return *(const int *)a != *(const int *)b;
}

int where_Nth_int(int key, int *arr, size_t nelm, int N) {
    int *w = lfind_Nth(&key, arr, &nelm, sizeof(*arr),
                       compar_int, N);
    return w ? w - arr : -1;
}

int main (void) {
    int arr[] = {2,3,4,1,2,};
    int nelm = sizeof(arr)/sizeof(*arr);
    printf("Second 2 @ %d\n", where_Nth_int(2, arr, nelm, 2));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...