簡體   English   中英

如何返回給定單詞/模式的所有出現的矩陣?

[英]How to return a matrix of all occurrences of given word/pattern?

我正在嘗試實現一個名為 Sniffer 的 function,它獲取兩個輸入並返回相應的矩陣。

第一個輸入是 integer 二進制數組值(只有零或一)

第二個輸入是您搜索的單詞(您選擇它作為 function 的參數的單詞)

function的功能:

在給定的二進制數組中搜索給定單詞的出現。 在您的單詞每次出現時,它后面總是跟着 8 位,假設輸入總是正確的(這意味着在沒有至少 8 位空間(8 個二進制值)的情況下,不可能兩次出現一個接一個地發生。)。

然后 function 必須為每個出現的單詞返回一個矩陣(整數矩陣),該矩陣由隨后的 8 位矩陣的每一行對應的單詞排序。 (函數只返回搜索詞每次出現后的前 8 位)

這表示:

First row has first 8 followed bit on first occurrence of the word.
Second row has first 8 followed bit on second occurrence of the word.
Third row has first 8 followed bit on third occurrence of the word.
Fourth row has first 8 followed bit on fourth occurrence of the word.
etc ...

我將通過示例詳細說明: function 結構是代碼:

int ** SnifferPattern(int* givenArray , int* SearchedWord);
//it returns the corresponded matrix so used int** ;

示例 1:

givenArray = {1,0,1,0,1,1,1,1,1,1,1,1,0,0};
SearchedWord = {1,0,1,0}; 

so the function returns a matrix(size 1x8 - 8 corresponds to 8followed bit) 
the first row is {1,1,1,1,1,1,1,1}, which is the first 8 bit followed 
the word 1010 the matrix here with one row because there's just 
one occurrence of the `SearchedWord` in the given array.

示例 2:

givenArray = {1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,1,0,1,0,1,0};
SearchedWord = {1,1,0,0} 

so the function returns a matrix the first row is {1,1,1,1,1,1,1,1} 
which is the first 8 bit followed the word 1010 for the first occurrence. 
for the second occurrence we see the word appear , so the second row of 
the returned matrix(size 2x8) will include the first 8bit followed the 
word 1010 of the second occurrence. so second row of the matrix 
is {1,0,1,0,1,0,1,0} so the returned matrix (size 2x8) has two rows 
(because there's two occurrences of the SearchedWord) which each row 
corresponds to each occurrence of the SearchedWord.

示例 3:

givenArray = {1,1,1,0,1,1,1,1,1,1,1,1,0,0}; 
SearchedWord = {0,1,0} 

so the function returns a matrix zero row (like an array with zero values) 
size 1x8 (8 columns is corresponded to 8followed bit). There's no 
occurrence of the SearchedWord within the givenArray so we return a zero 
matrix. There's no overlap between the occurrences of the searchedWords ,
so we assume always correctness of input.

我將解釋我的算法(如果有其他建議更符合我的情況,我很高興)

我的算法是在每次出現時搜索單詞,然后在每次出現時取第一個跟隨的 8 位。 我把它們存儲在矩陣的行中。 但這聽起來很難完成。

我在 C 中成功/嘗試實現的是:

int ** SnifferPattern(int* s ; int* w)
{
    // s is the given array, w is the searched Word , number occurrences      
    // here 2 , so it should be two prints on the output of the program.
    int n;         
    int a[1000];    
    int i=0;        
    int j;          
    int k = 0;      
    int l;         
    int found = 0;  
    int t = 0;      
 
    a[k++] = i; 
    j = 0;       
    for (i = 0; i < k; i++) 
    {
        n = a[i] - j;   
        if (n == (sizeof(w)/sizeof(w[0]))) 
        {
            t = 0;
            for (l = 0; w[l]; l++)  
            {
                if (s[l + j] == w[l])
                {
                    t++;  // Matched a character.
                }
            }
            
            if (t == (sizeof(w)/sizeof(w[0]))) 
            {
                found++;  // We found a match!
                printf("word occurred at location=%d \n", j);  // Pint location
            }
        }
        j = a[i] + 1; 
    }
}

int main() {

    int s[1000] = {1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1};
    int w[1000] = {1,0,1}; 
    
    // s is the given array, w is the searched Word , number occurrences      
    // here 2 , so it should be two prints on the output of the program.
    
    SnifferPattern(s , w)
    
   //I should print all the matrix's row in the main function .
    return 0;
}

我想我已經知道你需要什么了。 而且,正如您的問題中所述( “在您的單詞每次出現時,總是跟隨 8 位” ),以下要求至少 8 個整數跟隨w中的任何匹配s 由於您將在返回的矩陣的每一行中包含 8 個整數,因此使用指向數組的指針int[8]允許調用者中的單個free()結果。

Your sniffer function will loop over each integer in s keeping a counter index ( ndx ) of each time an integer in w matches the integer in s . ndx等於w中的元素數時,已找到匹配項,並且使用next8作為索引將接下來的 8 個整數收集為矩陣該行中的列。 您可以將您的嗅探器 function 編寫為:

#define AFTER    8

/* function returning allocated pointer to array of 8 int, *n of them */
int (*sniffer (int *s, int selem, int *w, int welem, int *n))[AFTER]
{
    int ndx = 0,                    /* match index */
        next8 = AFTER,              /* counter for next 8 after match found */
        found = 0,                  /* number of tiems w found in s */
        (*matrix)[AFTER] = NULL;
    
    for (int i = 0; i < selem; i++) {           /* loop over each int in s */
        if (next8 < AFTER) {                    /* count if next8 less than AFTER */
            matrix[found-1][next8++] = s[i];    /* set next8 index in matrix row */
        }
        else if (s[i] == w[ndx]) {              /* if s[i] matches w[ndx] */
            if (++ndx == welem) {               /* increment ndx, compare w/welem */
                /* allocate storage for next row in matrix */
                if (!(matrix = realloc (matrix, (found + 1) * sizeof *matrix))) {
                    perror ("realloc-matrix");  /* on failure, handle error */
                    *n = 0;
                    return NULL;
                }
                /* (optional) set all elements in row 0 */
                memset (matrix[found], 0, sizeof *matrix);
                found += 1;                     /* increment found count */
                ndx = next8 = 0;                /* reset ndx, set next8 to count */
            }
        }
        else            /* otherwise, not a match and not counting */
            ndx = 0;    /* set match index to 0 */
    }
    
    *n = found;         /* update value at n to found, so n available in main */
    
    return matrix;      /* return allocated matrix */
}

注: s中的元素個數由selem提供, w中的元素個數由welem提供)

將 main 中的s[]更改為int s[] = {1,0,1,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0}所以很容易驗證結果,你可以把你的程序寫成:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ARSZ  1000      /* if you need a constant, #define one (or more) */
#define AFTER    8

/* function returning allocated pointer to array of 8 int, *n of them */
int (*sniffer (int *s, int selem, int *w, int welem, int *n))[AFTER]
{
    int ndx = 0,                    /* match index */
        next8 = AFTER,              /* counter for next 8 after match found */
        found = 0,                  /* number of tiems w found in s */
        (*matrix)[AFTER] = NULL;
    
    for (int i = 0; i < selem; i++) {           /* loop over each int in s */
        if (next8 < AFTER) {                    /* count if next8 less than AFTER */
            matrix[found-1][next8++] = s[i];    /* set next8 index in matrix row */
        }
        else if (s[i] == w[ndx]) {              /* if s[i] matches w[ndx] */
            if (++ndx == welem) {               /* increment ndx, compare w/welem */
                /* allocate storage for next row in matrix */
                if (!(matrix = realloc (matrix, (found + 1) * sizeof *matrix))) {
                    perror ("realloc-matrix");  /* on failure, handle error */
                    *n = 0;
                    return NULL;
                }
                /* (optional) set all elements in row 0 */
                memset (matrix[found], 0, sizeof *matrix);
                found += 1;                     /* increment found count */
                ndx = next8 = 0;                /* reset ndx, set next8 to count */
            }
        }
        else            /* otherwise, not a match and not counting */
            ndx = 0;    /* set match index to 0 */
    }
    
    *n = found;         /* update value at n to found, so n available in main */
    
    return matrix;      /* return allocated matrix */
}

int main (void) {
    
    int s[] = {1,0,1,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0},
        w[] = {1,0,1},
        n = 0,
        (*result)[AFTER] = NULL;
    
    result = sniffer (s, sizeof s/sizeof *s, w, sizeof w/sizeof *w, &n);
    
    for (int i = 0; i < n; i++) {                       /* loop over result matrix */
        printf ("matrix[%d] = {", i);                   /* output prefix */
        for (int j = 0; j < AFTER; j++)                 /* loop over column values */
            printf (j ? ",%d" : "%d", result[i][j]);    /* output column value  */
        puts ("}");                                     /* output suffix and \n */
    }
    
    free (result);      /* free allocated memory */
}

示例使用/輸出

$ ./bin/pattern_in_s
matrix[0] = {0,0,0,0,1,1,1,1}
matrix[1] = {1,1,1,1,0,0,0,0}

如果我誤解了您的問題,請在下面的評論中告訴我,我很樂意為您提供進一步的幫助。 如果您有任何問題,請告訴我。

您必須解決幾個問題。

arrays 是如何表示的?

您有 arrays 整數,其有效值可以是 0 或 1。您如何確定數組的長度。 基本上有兩種可能:

  • 使用哨兵值。 這就是 C 字符串的存儲方式:實際字符串由特殊值'\0'終止,即 null 終止符。 用於存儲字符串的 memory 可能更大。 在您的情況下,您可以使用未使用的值:

     enum { END = -1 }; int a[] = {0, 1, 0, 1, END};

    這里的缺點是您必須小心不要忘記顯式終止符。 另外,如果你想找出一個數組的長度,你必須把它走到最后。 (但這不是小型 arrays 的問題。)

  • 使用與數組一起使用的顯式長度。

     int a[] = {1, 0, 1, 0}; int alen = sizeof(a) / sizeof(*a);

    這里的缺點是您必須將長度傳遞給對數組進行操作的任何 function。 function f(a)不知道 kow long a是; function 應該類似於f(a, alen) sizeof(a) / sizeof(*a)機制僅在數組a在 scope 中時有效。有關如何查找數組長度的討論, 請參見此處。)

    當然,您可以定義一個結合了數據和長度的結構。

如何從 function 返回一個數組?

那是你的實際問題。 同樣有幾種可能性:

  • 返回數組。 這通常意味着使用malloc在堆上分配要返回的數組,這意味着調用者必須在某個時間對結果調用free 調用者必須知道返回的數組有多大。 您可以使用如上所述的哨兵,也可以傳入指向 sive 變量的指針,function 填寫:

     int **f(..., int *length) {... }

    像這樣調用這個 function:

     int length; int **p = f(..., &length); for (int i = 0; i < length; i++)...
  • 傳入一個數組並用 function 填充它。 這意味着 function 必須知道數組的大小。 返回值可用於返回數組的實際大小:

     int f(..., int **res, int max) {... }

    像這樣調用這個 function:

     int *p[20]; int length = f(..., p, 20); for (int i = 0; i < length; i++)...

讓我們將此應用於您的問題。

您想匹配字符串中的模式,然后在匹配后返回所有 8 位序列的列表。 讓我們將數組表示為數組 + 長度。 您的 function 可能如下所示:

int sniffer(const int *s, int slen,         // haystack array + length
            const int *w, int wlen,         // needle array + length
            const int **res, int reslen)    // results array
{ ... }

它傳入 arrays sw加上它們的長度。 它還傳入第三個數組加上它的長度。 該數組保存結果。 有效結果的數量——矩陣中的行數——是返回值。

稱之為 function:

int s[] = {...};
int w[] = {...};

const int *res[8];
int n = sniffer(s, sizeof(s) / sizeof(*s),
                w, sizeof(w) / sizeof(*w),
                res, sizeof(res) / sizeof(*res));                    

如果有多個reslen匹配會發生什么? 當然,超出的匹配項不能寫入,但它們對返回值有貢獻嗎? 如果是這樣,您可以傳入一個長度為 0 的數組,以查看有多少匹配項。 (這就是字符串 function snprintf在某種程度上所做的事情。)如果他們沒有得到結果數組的確切長度。 兩種策略都有效。

這是一個示例實現。 它使用您的測試用例#2:

#include <stdlib.h>
#include <stdio.h>

/* 
 *  test whether the next len elements of s and w match
 */
int match(const int *s, const int *w, int len)
{
    while (len-- > 0) {
        if (*s++ != *w++) return 0;
    }
    
    return 1;
}

int sniffer(const int *s, int slen,         // haystack array + length
            const int *w, int wlen,         // needle array + length
            const int **res, int reslen)    // results array
{
    int n = 0;
    
    for (int i = 0; i <= slen - wlen - 8; i++) {
        const int *p = s + i;
    
        if (match(p, w, wlen)) {
            if (n < reslen) res[n] = p + wlen;
            n++;
        }
    }  
  
    return n;
}



int main(void)
{
    int s[] = {1, 1, 0, 0, 1, 1, 1, 1,
               1, 1, 1, 1, 1, 1, 0, 0,
               1, 0, 1, 0, 1, 0, 1, 0};
    int w[] = {1, 1, 0, 0};

    const int *res[8];
    int reslen = sizeof(res) / sizeof(*res);
    
    int n = sniffer(s, sizeof(s) / sizeof(*s),
                    w, sizeof(w) / sizeof(*w),
                    res, reslen);                    

    printf("%d patterns:\n", n);
    for (int i = 0; i < n && i < reslen; i++) {
        printf("[%d] {", i);
        
        for (int j = 0; j < 8; j++) {
            if (j) printf(", ");
            printf("%d", res[i][j]);
        }
        
        printf("}\n");
    }

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM