删除 k 个最后出现的列表元素

Posted

技术标签:

【中文标题】删除 k 个最后出现的列表元素【英文标题】:Delete k lasts occurences of a list element 【发布时间】:2021-12-31 00:26:41 【问题描述】:

目前我正在研究一个删除我选择的列表元素的最后出现次数的函数。我通过实现一个删除最后一个列表元素的函数,我想知道如何编写我的最后一个函数。

删除最后一次出现的特定元素的功能:

void DeleteLastOccurence(int x, List *l)

    List *p = l;
    List *m = NULL;
    while(*p != NULL)
    
        if((**p).number == x)
        
            m = p;
        
        p = &(**p).next;
    
    if(m != NULL)
    
        depile(m);
    

我的列表结构:

typedef struct Block

    int number;
    struct Block *next;
 Block;

typedef Block *List;

depile 子函数,删除参数中列表的第一个元素:

void depile(List *L)

    List tmp = *L ;
    *L = Lnext(*L) ;
    free(tmp) ;

和 Lnext 子函数,返回一个新的 List 对应于一个 in 参数没有它的第一个元素:

Liste Lnext(List l)

    return l->next;

我用列表 [2;1;1;2;4;4;4;4] 和 x = 2 测试我当前的功能,我得到 [2;1;1;4;4;4; 4]。

我的终端屏幕:

我想我需要添加一个整数 k 来删除元素的最后 k 个匹配项。

在我的最后一个函数中,使用相同的列表,x = 4 和 k = 3,我应该得到列表 [2;1;1;2;4]。

所以我想知道我是否可以稍微修改一下这个函数以获得最终版本?

例如,之前我实现了一个删除第一次出现的列表元素的功能:

void DeleteFirstOccurence(int x, Liste *l)

    if(isEmpty(*l))
    
        return;
    
    else
    
        if(x == firstElement(*l))
        
            depile(l);
        
        else
        
            DeleteFirstOccurence(x, &(*l)->suivant);
        
    

带有 FirstElement 和 isEmpty 子函数:

int FirstElement(List l)

    return l->number ; 

bool isEmpty(List l)

    return l == NULL ;


通过使用它,我能够实现消除前 k 次出现的功能:

void DeleteKfirstsOccurrences(int x, int k, List *l)

    if(isEmpty(*l))
    
        return;
    
    else
    
        for(int i = 0; i < k; ++i)
        
            if(x == FirstElement(*l))
            
                depile(l);
            
            else
            
                DeleteFirstOccurence(x, &(*l)->next);
            
        
    

x = 0 和列表 [4;2;0] 的 DeleteFirstOccurence 和 x = 5、k = 5 和列表 = 2 1 1 2 4 4 4 4 的 DeleteKFirstsOccurences:

如果有可能对我的第一个函数执行类似的过程以获得所需的结果,知道结构不一样并且我个人没有成功。

P.S : 在我的不同函数中,如果 k > x 在列表中的出现次数,则删除所有出现。

感谢您的宝贵时间和不同的建议,

真诚的。

(对不起我的英语水平,我通常不会写这么多)

【问题讨论】:

我喜欢depile,但它可能更符合pop 的习惯。 【参考方案1】:

它可能不是很优化,但它通过将函数放在 for 循环中来工作:

void DeleteKLastOccurences(int x, int k, List *l)

    for(int i = 0; i < k; i++)
    
        DeleteLastOccurence(x, l);
    

在那之后,肯定会有更好的东西。

【讨论】:

x 是要删除的元素,k 是出现次数。如果出现次数 downto 运算符的典型用例:while (k --&gt; 0) DeleteLastOccurence(x, l); @chqrlie 谢谢,我不认识这个运营商! 这不是一个实际的操作符,只是写(k-- &gt; 0)的一种有趣的方式,但是这个成语很有价值,恕我直言。【参考方案2】:

查看您的代码,我可以看到您使用的不是列表,而是linked list。

如果我正确理解您的问题,您想删除 n 出现的 x 元素的数量。

为此,您需要解析列表以查找要删除的所有元素,您可以存储它们,也可以只存储您需要开始删除的位置n,例如:

int countInstances(int element, List l) 
    List * temp = l;
    int counter = 0;
    while (temp) 
        if (temp.number == element)
            counter ++
        temp = temp.next;
    
    return counter;

如果您有一个列表 [0,1,1,3,3,3,3,3],并且您想删除 最后 4 个数字 3 的出现,使用上面的函数您可以看到您有 5 个数字 3 的实例, 因为你想删除最后的 4 你需要忽略 1 并删除所有其余的。

在使用链表时有一个标准的删除功能会很有帮助,例如

void linked_delete(int index, linkedList &list)

您可以找到更多信息here

编辑:

我刚刚意识到计数器函数是错误的,因为它忽略了最后一个元素,假设您列表中的最后一个 nextNULLnullptr 新的应该可以工作。

【讨论】:

是的,它们是链表,只是我的老师只是称它们为链表,所以我习惯了。对不起 否则最后给出的解释很符合我的要求。 但是,我将看看如何修复计数器,因为它通常可以工作,但如果我在列表中使用它作为 [1,2,4,4,4,4] 和 x = 4,程序帐户出现 3 次 4。 @mxbr236,您准备好接受使用 C++ 和算法深度优先搜索解决您的问题了吗? lists 在 C 中链表,就像在 Python 之前的大多数编程语言中一样。

以上是关于删除 k 个最后出现的列表元素的主要内容,如果未能解决你的问题,请参考以下文章

如何删除一个list中最后一个元素

力扣 练习2(十题)

力扣 练习2(十题)

力扣 练习2(十题)

vector中删除第k个元素的巧妙方法

Python 中删除列表元素的三种方法