迷爱

文章 评论 浏览 28

迷爱 2025-02-20 23:52:43

我想我终于明白了为什么它不起作用。显然,注册通知处理程序还不够:

app.Services.AddTransient(typeof(NotificationLogger<>));

您必须这样注册:

services.AddTransient(typeof(INotificationHandler<>),typeof(NotificationLogger<>));

I think I finally got why it wasn't working. Apparently, registering the notification handler like this isn't enough:

app.Services.AddTransient(typeof(NotificationLogger<>));

You must register it like this:

services.AddTransient(typeof(INotificationHandler<>),typeof(NotificationLogger<>));

MediaTR通用通知处理程序未调用

迷爱 2025-02-20 23:10:51

问题之所以发生,是因为您正在从您的应用程序中导入“ appModule”

儿童模块(是否负载)应导入 commonModule 到儿童模块)。

The problem is happening because you are importing the "AppModule" from your child module "LoggedAppModule"

In your app, nothing should import the App module (assuming this is the root module of your app).

The child modules (lazzy-loaded or not) should import the CommonModule (which shares the AppModule imports to the child modules).

如何解决“ browsermodule”已经加载了。在角度

迷爱 2025-02-20 21:37:23

设置cookie:res.cookie('name',value,{httponly:true,expires:expire})

获取cookie:req.cookies ['cookie-name']

然后在客户端版本中,例如,如果您使用Axios提出请求,则需要使用Credentials 启用属性

set a cookie: res.cookie('name', value, { httpOnly: true, expires: expire })

get a cookie: req.cookies['cookie-name']

then in client version for example if you make a request with axios you need to enable property withCredentials

如何在Express Typescript中获取cookie

迷爱 2025-02-20 14:07:07

似乎没有简单的方法在Python中使用FFMPEG,因此我建议您安装一个软件包,例如 ffmpeg-python 。如果您坚持使用FFMPEG,请按照上述解决方法在这里 尽管。这避免了您的第二个问题,这是由于将环境路径设置为文件夹而产生的,然后尝试打开文件

It seems as though there is no easy way to use ffmpeg in python, so I would recommend you install a package such as ffmpeg-python instead. If you are insistent on using ffmpeg, follow the workarounds mentioned here though. This avoids your second issue, which arises from setting the environment path to a folder and then try to open a file

无法安装hightpy

迷爱 2025-02-20 13:09:43

只是一个想法或骇客。

div {
  background-color: blue;
  width: 10%;
  transition: background-color 0.5s, width 0.5s;
  font-size: 0;
}

div:hover {
  width: 20%;
  background-color: red;
}
  
img {
  width: 100%;
  height: auto;
  visibility: hidden;
}
<div>
  <!-- use an image with target aspect ratio. sample is a square -->
  <img src="http://i.imgur.com/9OPnZNk.png" />
</div>

Just an idea or a hack.

div {
  background-color: blue;
  width: 10%;
  transition: background-color 0.5s, width 0.5s;
  font-size: 0;
}

div:hover {
  width: 20%;
  background-color: red;
}
  
img {
  width: 100%;
  height: auto;
  visibility: hidden;
}
<div>
  <!-- use an image with target aspect ratio. sample is a square -->
  <img src="http://i.imgur.com/9OPnZNk.png" />
</div>

维持使用CSS的DIV的纵横比

迷爱 2025-02-20 10:15:33

我认为在VUE3中,没有“丑陋”解决方案是不可能的,请参阅此处的灵感。但是我认为,最清洁的方法是只用其中一行代码创建一种方法。

I think in Vue3 that is not possible without 'ugly' solutions, see here for inspiration. But I think the cleanest way is to just create a method with that one line of code in it.

vuejs:单击时将标签内容复制到剪贴板而不创建功能

迷爱 2025-02-20 03:03:12

由于df2不包含数千个元素,因此您可以收集所有数据并像这样编写一个UDF:

df2_list = df2.collect()
d = sc.broadcast(dict([(c[0], c[1]) for c in df2_list]))
replace = f.udf(lambda x: d.value[x])

# then you can use replace on any dataframe like this;
df1.withColumn("gender", replace("gender")).show()
+-----+------+
| name|gender|
+-----+------+
| Andy|     1|
|Julie|     2|
|Danny|     1|
+-----+------+

我不确定它更简单,但这是另一种方法。

NB:广泛的演员不是强制性的,但是它将允许单词仅发送给每个执行人一次,而不是每个任务。

Since df2 does not contain more than a few thousand elements, you can collect all the data and write a udf like this:

df2_list = df2.collect()
d = sc.broadcast(dict([(c[0], c[1]) for c in df2_list]))
replace = f.udf(lambda x: d.value[x])

# then you can use replace on any dataframe like this;
df1.withColumn("gender", replace("gender")).show()
+-----+------+
| name|gender|
+-----+------+
| Andy|     1|
|Julie|     2|
|Danny|     1|
+-----+------+

I am not sure it is simpler, but it is another way at it.

NB: the broad cast is not mandatory, but it will allow the dictionary to be sent to each executor only once instead of every single task.

直接替换Pyspark列中的值,而无需加入

迷爱 2025-02-19 10:58:38

我在代码中发现了几个错误:

  mov eax,[vbe_mode_info.framebuffer]
mov dword [vbe_screen.physical_buffer],eax
 

在A dword 中写入字节大小的变量 .physical_buffer db 0

  mov eax,0
mov al,[.bpp]
mov byte [vbe_screen.bpp],al
Shr Eax,3
mov dword [vbe_screen.bytes_per_pixel],eax
 

单词大小变量 .bytes_per_pixel dw 0中写下 dword 。这损坏了指向线性框架缓冲区的指针,该线性框架缓冲区可能在写入内存后会产生灾难性的结果!


您永远不会检查VESA版本。尽管如此,您还是应该因为所需的FrameBuffer Pointer physbaseptr 仅包含在VESA版本2.0及更好的ModeInformation块中。

I found a couple of errors in the code:

mov eax, [vbe_mode_info.framebuffer]
mov dword[vbe_screen.physical_buffer], eax

writes a dword in a byte-sized variable .physical_buffer db 0.

mov eax, 0
mov al, [.bpp]
mov byte[vbe_screen.bpp], al
shr eax, 3
mov dword[vbe_screen.bytes_per_pixel], eax

writes a dword in a word-sized variable .bytes_per_pixel dw 0. This corrupts the pointer to the Linear Frame Buffer which can produce disastrous results upon writing to memory!


You never check the VESA version. You should nonetheless because the framebuffer pointer PhysBasePtr that you need, is only included in the ModeInformation block for VESA versions 2.0 and better.

如何在VMware或VirtualBox中使用VESA模式?

迷爱 2025-02-19 10:30:26

使用Pyecharts渲染到图像一直是开发人员感兴趣的功能。 Pyecharts通过三种方式提供硒,phantomjs和Pyppeteer。

pip install snapshot-selenium
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot

from snapshot_selenium import snapshot

def bar_chart() -> Bar:
    c = (
        Bar()
        .add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
        .add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
        .add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
        .reversal_axis()
        .set_series_opts(label_opts=opts.LabelOpts(position="right"))
        .set_global_opts(title_opts=opts.TitleOpts(title="Bar-测试渲染图片"))
    )
    return c

make_snapshot(snapshot, bar_chart().render(), "bar0.png")
  1. phantomjs
pip install snapshot-phantomjs
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot

from snapshot_phantomjs import snapshot

def bar_chart() -> Bar:
    c = (
        Bar()
        .add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
        .add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
        .add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
        .reversal_axis()
        .set_series_opts(label_opts=opts.LabelOpts(position="right"))
        .set_global_opts(title_opts=opts.TitleOpts(title="Bar-测试渲染图片"))
    )
    return c

make_snapshot(snapshot, bar_chart().render(), "bar0.png")
  1. pyppeteer
pip install snapshot-pyppeteer

# then, you need install chromium
pyppeteer-install
from snapshot_pyppeteer import snapshot

from pyecharts.charts import Bar
from pyecharts.faker import Faker
from pyecharts import options as opts
from pyecharts.render import make_snapshot


def bar_base() -> Bar:
    c = (
        Bar()
        .add_xaxis(Faker.choose())
        .add_yaxis("商家A", Faker.values())
        .add_yaxis("商家B", Faker.values())
        .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="我是副标题"))
    )
    make_snapshot(snapshot, c.render(), "bar.png")


if __name__ == '__main__':
    bar_base()

Rendering to images using pyecharts has always been a feature of interest to developers. pyecharts provides selenium, phantomjs and pyppeteer in three ways.

  1. selenium
pip install snapshot-selenium
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot

from snapshot_selenium import snapshot

def bar_chart() -> Bar:
    c = (
        Bar()
        .add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
        .add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
        .add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
        .reversal_axis()
        .set_series_opts(label_opts=opts.LabelOpts(position="right"))
        .set_global_opts(title_opts=opts.TitleOpts(title="Bar-测试渲染图片"))
    )
    return c

make_snapshot(snapshot, bar_chart().render(), "bar0.png")
  1. phantomjs
pip install snapshot-phantomjs
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot

from snapshot_phantomjs import snapshot

def bar_chart() -> Bar:
    c = (
        Bar()
        .add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
        .add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
        .add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
        .reversal_axis()
        .set_series_opts(label_opts=opts.LabelOpts(position="right"))
        .set_global_opts(title_opts=opts.TitleOpts(title="Bar-测试渲染图片"))
    )
    return c

make_snapshot(snapshot, bar_chart().render(), "bar0.png")
  1. pyppeteer
pip install snapshot-pyppeteer

# then, you need install chromium
pyppeteer-install
from snapshot_pyppeteer import snapshot

from pyecharts.charts import Bar
from pyecharts.faker import Faker
from pyecharts import options as opts
from pyecharts.render import make_snapshot


def bar_base() -> Bar:
    c = (
        Bar()
        .add_xaxis(Faker.choose())
        .add_yaxis("商家A", Faker.values())
        .add_yaxis("商家B", Faker.values())
        .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="我是副标题"))
    )
    make_snapshot(snapshot, c.render(), "bar.png")


if __name__ == '__main__':
    bar_base()

PYECHARTS:如何将Pyecharts保存为PNG?

迷爱 2025-02-19 07:00:47

看起来您的错误不是由安装本身引起的,而是由于OpenShift安全性“功能”,该功能在每个安装时都会更改允许的UID/GID范围。提供更多信息可用在这里;就我个人而言,我发现通常可以通过战略性地避免使用特定的UID来为服务使用特定的UID,但这也许不是您的选择。

It looks like your error is not arising from the install itself, but from an OpenShift security "feature" that changes the permitted UID/GID range with each installation. More info is available here; personally I have found that it's usually possible to avoid the use of specific UIDs for services entirely by chmod-ing strategically, but perhaps that's not an option for you.

在OpenShift中安装伪像掌舵图表的错误

迷爱 2025-02-19 05:26:15

要回答特定的问题,您可以使用 session helper 并在注册功能中的会话中写入电话号码:

public function register(Request $request)
    {
        // Validation Data
        $validData = $this->validate($request, [
            'user_input' => 'required|unique:users,usr_name|unique:members,mbr_mobile|regex:/^09\d{9}$/|max:11|min:11',
        ]);

        session(['user_phone_number' => $request->input('user_input')]);
        
       // rest of the code ...
    }

and than retrieve it from session in verifyCode:

public function verifyCode(Request $request)
    {
        $user_phone_number = session('user_phone_number');
        if(!$user_phone_number){
          //TODO: handle missing phone number from session
        }

        // rest of the code
    }

However, better approach would be if you make another Model / Db table "TempUser" and store user data there.

我的方法是我不会验证电话号码。我认为检查通过SMS发送的“验证代码”足够。

To answer specific question, you could use session helper and write phone number in session in register function:

public function register(Request $request)
    {
        // Validation Data
        $validData = $this->validate($request, [
            'user_input' => 'required|unique:users,usr_name|unique:members,mbr_mobile|regex:/^09\d{9}$/|max:11|min:11',
        ]);

        session(['user_phone_number' => $request->input('user_input')]);
        
       // rest of the code ...
    }

and than retrieve it from session in verifyCode:

public function verifyCode(Request $request)
    {
        $user_phone_number = session('user_phone_number');
        if(!$user_phone_number){
          //TODO: handle missing phone number from session
        }

        // rest of the code
    }

However, better approach would be if you make another Model / Db table "TempUser" and store user data there.

My approach would be that I would not validate phone number. I think checking "verifyCode" that was sent via sms in enough.

如何在Laravel API控制器中发送会话

迷爱 2025-02-17 22:13:58

我们可以通过多种方式对此进行推论。

例如,想象以下控制器:

import { Body, Controller, Get, HttpStatus, Res } from "@nestjs/common";

export class TestDto {
  hello?: string;
}

@Controller()
export class TestController {
  @Get()
  public async create(
    @Body() testDto: TestDto,
    @Res() res: any
  ): Promise<string> {
    res
      .status(HttpStatus.BAD_REQUEST)
      .json({ message: "i'm testting a bad request" });

    return testDto.hello ?? "hello is missing";
  }
}

我们可以测试对statusJSON的调用:

describe("TestController", () => {
  let controller: TestController;

  const mockJson = jest.fn().mockImplementation(() => null),
    mockStatus = jest.fn().mockImplementation(() => ({ json: mockJson })),
    mockResponse = {
      status: mockStatus,
    },
    mockDto = { hello: "world" };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [TestController],
    }).compile();

    controller = module.get(TestController);
  });

  beforeEach(async () => {
    await controller.create(mockDto, mockResponse);
  });

  it("checks call to status", () => {
    expect(mockStatus).toHaveBeenCalledWith(HttpStatus.BAD_REQUEST);
  });

  it("checks call to json", () => {
    expect(mockJson).toHaveBeenCalledWith({
      message: "i'm testting a bad request",
    });
  });
});

There are many ways we can reason about this.

For example, imagine the following controller:

import { Body, Controller, Get, HttpStatus, Res } from "@nestjs/common";

export class TestDto {
  hello?: string;
}

@Controller()
export class TestController {
  @Get()
  public async create(
    @Body() testDto: TestDto,
    @Res() res: any
  ): Promise<string> {
    res
      .status(HttpStatus.BAD_REQUEST)
      .json({ message: "i'm testting a bad request" });

    return testDto.hello ?? "hello is missing";
  }
}

We can test the calls made to status and json:

describe("TestController", () => {
  let controller: TestController;

  const mockJson = jest.fn().mockImplementation(() => null),
    mockStatus = jest.fn().mockImplementation(() => ({ json: mockJson })),
    mockResponse = {
      status: mockStatus,
    },
    mockDto = { hello: "world" };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [TestController],
    }).compile();

    controller = module.get(TestController);
  });

  beforeEach(async () => {
    await controller.create(mockDto, mockResponse);
  });

  it("checks call to status", () => {
    expect(mockStatus).toHaveBeenCalledWith(HttpStatus.BAD_REQUEST);
  });

  it("checks call to json", () => {
    expect(mockJson).toHaveBeenCalledWith({
      message: "i'm testting a bad request",
    });
  });
});

如何在开玩笑中模拟嵌套响应对象参数?

迷爱 2025-02-17 18:47:56

实际上,我能够在不使用ID的情况下创建它 - 因为您将“此”传递给您的函数,所以您需要做的就是创建一个新元素,然后执行img.parentnode.insertbefore(newnode,img.nextsibling );。话虽这么说,最好添加ID。这是一个工作示例:

function showAlt(imgNode) {
    const altNode = document.createElement("p");
  altNode.innerHTML = imgNode.alt;
  
    imgNode.parentNode.insertBefore(altNode, imgNode.nextSibling);
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  </head>
  <body>
  <section class="container">
  <div class="thumbnailContainer">
      <img src="https://ursd.org/wp-content/uploads/2020/12/1.png" alt="TEXT FOR IMAGE" class="img-thumbnail border-0 img-thumbnail-desktop" style="max-width:140px;" onclick="showAlt(this);">
    </div>
  </section>
  </body>
</html>

如果您想稍微播放代码,这是一个JSFIDDLE - https:// jsfiddle。 NET/AJAX201222/6DZ18HWA/13/

I was actually able to create it without using the id - since you're passing "this" to your function, all you need to do is create a new element and do img.parentNode.insertBefore(newNode, img.nextSibling);. That being said, it might be better to add an id instead. Here's a working example:

function showAlt(imgNode) {
    const altNode = document.createElement("p");
  altNode.innerHTML = imgNode.alt;
  
    imgNode.parentNode.insertBefore(altNode, imgNode.nextSibling);
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  </head>
  <body>
  <section class="container">
  <div class="thumbnailContainer">
      <img src="https://ursd.org/wp-content/uploads/2020/12/1.png" alt="TEXT FOR IMAGE" class="img-thumbnail border-0 img-thumbnail-desktop" style="max-width:140px;" onclick="showAlt(this);">
    </div>
  </section>
  </body>
</html>

and in case you want to play with the code a bit, here's a JSFiddle - https://jsfiddle.net/AJax201222/6dz18hwa/13/

单击IMG下的ALT中显示ALT的文字

迷爱 2025-02-17 11:06:40

所有主要问题都是由于该字符串是信息的,同时被主动更改。

通常,单词不正确地标记。


用输入“ Hello World”作为示例,HelloEllolloloo在寻找 word 时将字符串化时,被视为单词。该程序仅在扫描单词时通过一个字符推进字符串。

该程序应延长字符串的当前令牌的长度。


number_of_word_occurrence在进行比较时考虑任何有效 Word 的子字符串。

对于输入

koristio sam auto- 停止 da dodjem do znaka 停止 ali prije 停止 sam otvorio dek stop kompjutera 停止

the maximum count is incorrectly found to be 5, for stop.该问题与上面的问题相加,并开始删除报告这种情况数的错误令牌数据。


要概括一下,这种方法的一个很大的问题是,当您从字符串中删除a word 时,下次的出现数量将有所不同找到它。 Looking at

hello hello hello world world

The max occurrence count of a word here is 3, for hello.循环删除最大 word 将首次查看Hello,检查其出现数量,找到它为3,max和max,并且删除它。

 hello hello world world

对于第二个Hello,由于字符串已更改,因此检查其出现计数现在将返回2。这不是3的最大值,因此字符串没有变化。


此外,由于更改的字符串不会被终止 - 仅此后。意味着搜索一个单词可能会读取过时的数据,从而产生不良结果。


对程序可以使用的功能的严格限制(对动态内存和辅助缓冲区的限制的特殊性)确实可以实现非常详尽的解决方案。

一种解决方案是首先发现字符串中任何 word 的最大出现 count 首先在字符串中出现。然后,做count times操作删除 word 的出现,它允许您始终拥有 first 外观作为比较点。

通过在字符串中覆盖所有内容(包括null末端字节),将其覆盖 word

这是一个粗略的示例 - 在很大程度上未经测试,但为所示示例提供了正确的结果。用-ddebug编译以查看其他信息。

#include <ctype.h>
#include <stdio.h>

typedef struct word {
    const char *base;
    size_t length;
} word;

#define length(s) (span((s), NULL))
size_t span(const char *base, int (*test)(int))
{
    const char *end = base;

    while (test ? test((unsigned char) *end) : *end)
        end++;

    return (size_t) (end - base);
}

int eql(word a, word b)
{
#ifdef DEBUG
    fprintf(stderr, "DEBUG: A{%zu}<<%.*s>> <=> B{%zu}<<%.*s>>\n",
            a.length, (int) a.length, a.base,
            b.length, (int) b.length, b.base);
#endif

    if (!a.length || !b.length || a.length != b.length)
        return 0;

    if (a.base == b.base)
        return 1;

    for (size_t i = 0; i < a.length; i++)
        if (tolower((unsigned char) a.base[i]) != tolower((unsigned char) b.base[i]))
            return 0;

    return 1;
}

word get_word(const char *s, const char **end)
{
    word w = { 0 };

    while (*s && !isalpha((unsigned char) *s))
        s++;

    w.base = s;
    w.length = span(s, isalpha);

    *end = (s + w.length);

    return w;
}


word find_last(const char *s, word mark, unsigned *count)
{
    word last = { 0 };
    unsigned c = 0;

    for (const char *end; *s; s = end) {
        word current = get_word(s, &end);

        if (eql(mark, current)) {
            last = current;
            c++;
        }
    }

    if (count)
        *count = c;

    return last;
}

word find_most_common(const char *s, unsigned *count)
{
    word most_common = { 0 };

    *count = 0;

    for (const char *end; *s; s = end) {
        word current = get_word(s, &end);

        if (eql(most_common, current))
            continue;

        unsigned c;

        (void) find_last(s, current, &c);

        if (c > *count) {
            most_common = current;
            *count = c;
        }
    }

    return most_common;
}

void copy(char *dest, char *source, size_t length)
{
    for (size_t i = 0; i < length; i++)
        dest[i] = source[i];
}

void remove_most_common(char *s)
{
    unsigned count = 0;
    word common = find_most_common(s, &count);

#ifdef DEBUG
    if (count)
        fprintf(stderr, "DEBUG: MOST COMMON WORD: [[%.*s]]x%u\n",
                (int) common.length, common.base, count);
#endif

    size_t len = length(s);

    while (count--) {
        word last = find_last(s, common, NULL);

        copy(
            (char *) last.base,
            (char *) last.base + last.length,
            len - (size_t) (last.base - s) + 1);

        len -= last.length;
    }
}

int main(void)
{
    char buffer[4096];

    if (!fgets(buffer, sizeof buffer, stdin))
        return 1;

    size_t len = length(buffer);

    if (len && buffer[len - 1] == '\n')
        buffer[len - 1] = 0;

    printf("<<%s>>\n", buffer);
    remove_most_common(buffer);
    printf("<<%s>>\n", buffer);
}

All the major issues are due to the fact that the string is a source of information, while being actively altered.

In general, words are not tokenized properly.


With the input "hello world" as an example, each of hello, ello, llo, lo, and o are considered words when tokenizing the string while looking for the word to remove. The program only advances the string by one character when scanning for words.

The program should advance the string by the length of the current token.


number_of_word_occurrence considers any substring a valid word when making comparisons.

For the input

Koristio sam auto-stop da dodjem do znaka stop ali prije stopa sam otvorio dekstop kompjutera stop

the maximum count is incorrectly found to be 5, for stop. This problem compounds with the problem above, and starts removing incorrectly tokenized data that reports this occurrence count.


To generalize, a large problem with this approach is that as you remove a word from the string, the number of occurrences is going to be different for that word, the next time it is found. Looking at

hello hello hello world world

The max occurrence count of a word here is 3, for hello. Looping through to remove the maximum word will see hello the first time, check its occurrence count, find it to be 3, the max, and remove it.

 hello hello world world

For the second hello, checking its occurrence count now will return 2, since the string was altered. This is not the max of 3, so the string is unchanged.


Additionally, the string is not null-terminated as it is altered - only afterwards. Meaning searching for a word might read stale data, giving bad results.


The strict limitation on what functionality the program can utilize (particularity the restrictions on dynamic memory and auxiliary buffers) does make for very exhaustive solutions.

One solution is to first discover the maximum occurrence count of any word in the string, and hold a pointer to this word's first appearance in the string. Then, do count times operations removing the last appearance of the word, which allows you to always have the first appearance as a point of comparison.

A word is removed by overwriting it with everything that follows it in the string (including the null-terminating byte).

Here is a cursory example - largely untested, but provides the correct results for the examples shown. Compile with -DDEBUG to see additional information.

#include <ctype.h>
#include <stdio.h>

typedef struct word {
    const char *base;
    size_t length;
} word;

#define length(s) (span((s), NULL))
size_t span(const char *base, int (*test)(int))
{
    const char *end = base;

    while (test ? test((unsigned char) *end) : *end)
        end++;

    return (size_t) (end - base);
}

int eql(word a, word b)
{
#ifdef DEBUG
    fprintf(stderr, "DEBUG: A{%zu}<<%.*s>> <=> B{%zu}<<%.*s>>\n",
            a.length, (int) a.length, a.base,
            b.length, (int) b.length, b.base);
#endif

    if (!a.length || !b.length || a.length != b.length)
        return 0;

    if (a.base == b.base)
        return 1;

    for (size_t i = 0; i < a.length; i++)
        if (tolower((unsigned char) a.base[i]) != tolower((unsigned char) b.base[i]))
            return 0;

    return 1;
}

word get_word(const char *s, const char **end)
{
    word w = { 0 };

    while (*s && !isalpha((unsigned char) *s))
        s++;

    w.base = s;
    w.length = span(s, isalpha);

    *end = (s + w.length);

    return w;
}


word find_last(const char *s, word mark, unsigned *count)
{
    word last = { 0 };
    unsigned c = 0;

    for (const char *end; *s; s = end) {
        word current = get_word(s, &end);

        if (eql(mark, current)) {
            last = current;
            c++;
        }
    }

    if (count)
        *count = c;

    return last;
}

word find_most_common(const char *s, unsigned *count)
{
    word most_common = { 0 };

    *count = 0;

    for (const char *end; *s; s = end) {
        word current = get_word(s, &end);

        if (eql(most_common, current))
            continue;

        unsigned c;

        (void) find_last(s, current, &c);

        if (c > *count) {
            most_common = current;
            *count = c;
        }
    }

    return most_common;
}

void copy(char *dest, char *source, size_t length)
{
    for (size_t i = 0; i < length; i++)
        dest[i] = source[i];
}

void remove_most_common(char *s)
{
    unsigned count = 0;
    word common = find_most_common(s, &count);

#ifdef DEBUG
    if (count)
        fprintf(stderr, "DEBUG: MOST COMMON WORD: [[%.*s]]x%u\n",
                (int) common.length, common.base, count);
#endif

    size_t len = length(s);

    while (count--) {
        word last = find_last(s, common, NULL);

        copy(
            (char *) last.base,
            (char *) last.base + last.length,
            len - (size_t) (last.base - s) + 1);

        len -= last.length;
    }
}

int main(void)
{
    char buffer[4096];

    if (!fgets(buffer, sizeof buffer, stdin))
        return 1;

    size_t len = length(buffer);

    if (len && buffer[len - 1] == '\n')
        buffer[len - 1] = 0;

    printf("<<%s>>\n", buffer);
    remove_most_common(buffer);
    printf("<<%s>>\n", buffer);
}

从c中的字符串中删除最常见的单词

迷爱 2025-02-17 03:11:37

您必须使用这样的值:

ChangeNotifierProvider.value(
  value: FindProvider(), // write again the provider, cause you gonna set the already value created before in FindScreen
  child: CustomWidget(),
)

Buuttt,我建议您将提供商全球放置,也就是说,您所有的应用程序都可以访问它,您没有,您没有一次又一次地给予价值...但是如何呢?好吧,而不是在Findscreen中创建它,而是在材料应用中创建它。

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider( // something like this or MultiProvider
      create: (BuildContext context) => FindProvider(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const HomeScreen(),
      ),
    );  
  }

You have to "re-create" your Provider to the CustomWidget with the .value like this :

ChangeNotifierProvider.value(
  value: FindProvider(), // write again the provider, cause you gonna set the already value created before in FindScreen
  child: CustomWidget(),
)

Buuttt, I recommend you to put your Provider globally, that is to say, that ALL your application has access to it and you don't have to give the value again and again and again... but how? Well, instead of creating it in your FindScreen, you create it in your MaterialApp.

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider( // something like this or MultiProvider
      create: (BuildContext context) => FindProvider(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const HomeScreen(),
      ),
    );  
  }

提供者可以在ShowBottTomsheet的状态小部件内消耗

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文