int KMPIndex(SqString s, SqString t, int indices[], int* count){//count用于存储每一行出现了多少次,indices存模式串在主串中出现的第一个位置 int next[1000], i = 0, j = 0,k=0;//k用于记录是否匹配成功 if (t.length == 0) { return -1; } GetNext(t, next); while (i < s.length) { if (j == -1 || s.data[i] == t.data[j]) { i++; j++; if(j == t.length) {//匹配成功 indices[*count] = i - j+1;//保存位置 (*count)++; j = -1;//继续查找 k = 1; } } else j = next[j]; } if (count == 0) { k = -1; } return k ; }void search(SqString s) { FILE *fp; int indices[1000] ; SqString w={}; int j = 0, u=0,num = 0, i = 0 ;//num用于记录出现次数 fopen_s(&fp,file_path, "r"); if (fp == NULL) { printf(" 无法打开文件!\n"); return; } while (fgets(w.data, sizeof(w.data),fp) != NULL) { w.length = strlen(w.data); int count = 0; if (w.data[w.length - 1] == '\n') { w.data[w.length - 1] = '\0'; // 将换行符替换为字符串结束符 w.length--; } i++; u = KMPIndex(w,s,indices, &count); if (u == 1 ) { num = num + count; printf(" 出现位置在第%d行,次数为%d\n",i,count); } } printf(" 【%s】共计出现%d次\n", s.data, num); }
时间: 2024-04-26 10:24:16 浏览: 81
这段代码是一个基于KMP算法实现的字符串匹配算法。其中,函数KMPIndex用于在主串s中查找模式串t,返回模式串在主串中第一次出现的位置,如果没有出现则返回-1。参数indices用于存储模式串在主串中出现的第一个位置,参数count用于存储每一行模式串出现的次数。函数search用于在指定文件中查找字符串s,并打印出现的位置和次数。
具体实现方式是,先打开指定文件,逐行读取文件中的字符串,然后调用KMPIndex函数查找字符串s在该行字符串中的出现次数,如果出现次数不为0,则累加到总出现次数中,并打印出现位置和次数。最后输出总出现次数。
需要注意的是,代码中使用了一个next数组,该数组是KMP算法中的next数组,用于优化匹配过程。另外,代码中出现了一些变量和常量,如i、j、k、num等,需要根据具体情况进行理解和使用。
相关问题
class TopNHotItems(topSize: Int) extends KeyedProcessFunction[Tuple, ItemViewCount, String] { private var itemState : ListState[ItemViewCount] = _ override def open(parameters: Configuration): Unit = { super.open(parameters) // 命名状态变量的名字和状态变量的类型 val itemsStateDesc = new ListStateDescriptor[ItemViewCount]("itemState-state", classOf[ItemViewCount]) // 从运行时上下文中获取状态并赋值 itemState = getRuntimeContext.getListState(itemsStateDesc) } override def processElement(input: ItemViewCount, context: KeyedProcessFunction[Tuple, ItemViewCount, String]#Context, collector: Collector[String]): Unit = { // 每条数据都保存到状态中 itemState.add(input) // 注册 windowEnd+1 的 EventTime Timer,当触发时,说明收齐了属于windowEnd 窗口的所有商品数据 // 也就是当程序看到 windowend + 1 的水位线 watermark 时,触发 onTimer 回调函数 context.timerService.registerEventTimeTimer(input.windowEnd + 1) } override def onTimer(timestamp: Long, ctx: KeyedProcessFunction[Tuple, ItemViewCount, String]#OnTimerContext, out: Collector[String]): Unit = { // 获取收到的所有商品点击量 val allItems: ListBuffer[ItemViewCount] = ListBuffer() import scala.collection.JavaConversions._ for (item <- itemState.get) { allItems += item } // 提前清除状态中的数据,释放空间 itemState.clear() // 按照点击量从大到小排序 val sortedItems = allItems.sortBy(_.count)(Ordering.Long.reverse).take(topSize) // 将排名信息格式化成 String, 便于打印 val result: StringBuilder = new StringBuilder() result.append("******************************\n") result.append("窗口结束时间: ").append(new Timestamp(timestamp - 1)).append("\n") for(i <- sortedItems.indices){ val currentItem: ItemViewCount = sortedItems(i) // e.g. No1: 商品 ID=12224 浏览量 =2413 result.append("No").append(i+1).append(":") .append(" 商品id=").append(currentItem.itemId) .append(" 热门度 =").append(currentItem.count).append("\n") } result.append("******************************") // 控制输出频率,模拟实时滚动结果 Thread.sleep(500) out.collect(result.toString) }
这段代码是什么意思?
这段代码定义了一个KeyedProcessFunction函数,输入参数是ItemViewCount类型的数据,输出参数是String类型的数据。在函数中,定义了一个ListState状态变量itemState,并在open()方法中初始化。在processElement()方法中,每次接收到一个ItemViewCount类型的数据,都将其保存到itemState状态变量中,并注册一个定时器,定时器的触发时间是当前ItemViewCount数据所属的窗口结束时间+1。
在onTimer()方法中,当定时器触发时,首先从itemState状态变量中获取所有的ItemViewCount数据,并清空itemState状态变量。然后按照点击量从大到小排序,取出前topSize个热门商品,并将其格式化成字符串输出。最后通过out.collect()方法将结果输出。
这个函数的作用是计算出每个窗口期间内的热门商品排行榜,并输出结果。
for (int i = 0; i < triangleCount * 3; ++i) { unsigned int code = indices[i]; indices[i] = highest - code; if (code == 0) { ++highest; } }如何反写回去
要将修改后的indices数组反写回去,可以再次使用一个循环遍历数组,将修改后的值重新写入到原始的indices数组中,示例代码如下:
```
for (int i = 0; i < triangleCount * 3; ++i) {
unsigned int code = indices[i];
indices[i] = highest - code;
if (code == 0) {
++highest;
}
}
// 反写回去
for (int i = 0; i < triangleCount * 3; ++i) {
unsigned int code = indices[i];
indices[i] = highest - code;
if (code == 0) {
++highest;
}
}
```
这样就可以将修改后的indices数组重新写回到原始的数组中了。需要注意的是,反写回去的操作和修改时的操作是一模一样的,因此需要再次遍历数组进行操作。
阅读全文