[英]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 s
和w
加上它們的長度。 它還傳入第三個數組加上它的長度。 該數組保存結果。 有效結果的數量——矩陣中的行數——是返回值。
稱之為 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.