删除 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 --> 0) DeleteLastOccurence(x, l);
@chqrlie 谢谢,我不认识这个运营商!
这不是一个实际的操作符,只是写(k-- > 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
编辑:
我刚刚意识到计数器函数是错误的,因为它忽略了最后一个元素,假设您列表中的最后一个 next
是 NULL
或 nullptr
新的应该可以工作。
【讨论】:
是的,它们是链表,只是我的老师只是称它们为链表,所以我习惯了。对不起 否则最后给出的解释很符合我的要求。 但是,我将看看如何修复计数器,因为它通常可以工作,但如果我在列表中使用它作为 [1,2,4,4,4,4] 和 x = 4,程序帐户出现 3 次 4。 @mxbr236,您准备好接受使用 C++ 和算法深度优先搜索解决您的问题了吗? lists 在 C 中是链表,就像在 Python 之前的大多数编程语言中一样。以上是关于删除 k 个最后出现的列表元素的主要内容,如果未能解决你的问题,请参考以下文章