无法从单链表中删除元音 [英] Cannot delete vowels from singly linked list

查看:176
本文介绍了无法从单链表中删除元音的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从链接的列表中删除元音时遇到问题。程序接受命令行参数,将它们组合在单个字符串中,并将每个字符添加到链接列表作为节点。

I am having an issue while deleting the vowel from a linked List. The program accept command line arguments, combines them in a single string and add each character to a linked list as node.

当我尝试使用命令行参数运行程序柠檬,成功地删除了元音。即如果参数不包含元音元音,程序会成功删除元音。
另一方面,如果我尝试使用命令行参数aeiou执行相同的操作,程序会崩溃消息分段错误(core dumped)..我不知道如何处理这个..

When i try to run the program with command line argument "lemon", the successfully deletes the vowels. i.e the program deletes the vowels successfully if the argument doesn't contain consequetive vowels. On the other hand, if i try to do the same with command line argument "aeiou", the program crashes with message Segmentation fault(core dumped).. I am not getting any idea how to handle this..

程序不能创建任何全局变量,所以我使用了双指针。
所有的功能都正常工作,这个问题可能由于locate()和removeVowels()函数中的一些错误而发生,但我无法弄明白错误是什么。

The program must not create any global variables so i've used double pointer. All the functions are working properly this problem may have occured due to some mistakes in locate() and removeVowels() function but i cannot figure out what the mistake is.


可以使用双指针来解决这个问题吗?
我不知道这个程序有什么问题..我是新的c编程,请帮助我这个..请纠正我..
提前感谢。

can this problem be solved using double pointer?? I cannot figure out what is wrong in this program.. I am new to c programming, please help me with this.. Please rectify me.. Thanks in advance.

完整的代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct linkedList {
    char ch;
    struct linkedList *node;
};
void printMenu(void);
char* combineWithNoSpaces(int, char *[]);
void addTolinkedList(char *, struct linkedList **, int *);
void printLinkedList(struct linkedList **);
struct linkedList *locate(struct linkedList**);
int delHead(struct linkedList **);
void removeVowels(struct linkedList**);
int isEmpty(struct linkedList **);

int main(int argc, char *argv[]) {
    int choice, indexer = 0;
    struct linkedList *s;
    char *string;
    if (argc == 1) {
        printf("Parse a sentence");
    } else {
        s = (struct linkedList *) malloc(sizeof(struct linkedList));
        string = combineWithNoSpaces(argc, argv);
        addTolinkedList(string, &s, &indexer);
        while (1) {
            printMenu();
            scanf("%d", &choice);
            if (choice == 1) {
                printLinkedList(&s);
            } else if (choice == 2) {
                if (!delHead(&s))
                    printf("Failed.Empty linked list");
            } else if (choice == 3) {
                removeVowels(&s);

            } else if (choice == 4) {
                if(isEmpty(&s)){
                    printf("Empty LinkedList");
                }
                else
                    printf("Not Empty");
            } else if (choice == 5) {
                break;
            } else
                printf("Invalic choice");
            printf("\n");
        }
    }
    return 0;
}

int isEmpty(struct linkedList **s){
    if(*s == NULL)
        return 1;
    else
        return 0;
}

struct linkedList *locate(struct linkedList **s) {
    if ((*s)->node->ch == 'a' || (*s)->node->ch == 'e' || (*s)->node->ch == 'i'
            || (*s)->node->ch == 'o' || (*s)->node->ch == 'u'
            || (*s)->node->ch == 'A' || (*s)->node->ch == 'E'
            || (*s)->node->ch == 'I' || (*s)->node->ch == 'O'
            || (*s)->node->ch == 'U') {
        return *s;
    } else if ((*s)->node->node == NULL) {
        return NULL;
    } else
        return locate(&((*s)->node));
}
void removeVowels(struct linkedList **s) {
    struct linkedList *temp, *tag;
    /* Checking whether the first node is null or not */
    if ((*s)->ch == 'a' || (*s)->ch == 'e' || (*s)->ch == 'i'
            || (*s)->ch == 'o' || (*s)->ch == 'u'
            || (*s)->ch == 'A' || (*s)->ch == 'E'
            || (*s)->ch == 'I' || (*s)->ch == 'O'
            || (*s)->ch == 'U')
        delHead(s);
    do {
        tag = locate(s);
        if (tag != NULL) {
            temp = tag->node->node;
            free(tag->node);
            tag->node = temp;
        }

    } while (tag != NULL);
}
int delHead(struct linkedList **s) {
    struct linkedList *temp;
    if ((*s) == NULL) {
        return 0;
    } else {
        temp = (*s)->node;
        free(*s);
        *s = temp;
        return 1;
    }
}
void printLinkedList(struct linkedList **s) {
    if ((*s) != NULL) {
        printf("%c", (*s)->ch);
        printLinkedList(&(*s)->node);
    }
    return;
}
void addTolinkedList(char *str, struct linkedList **s, int *indexer) {
    if (*indexer == strlen(str)) {
        *s = NULL;
        return;
    } else {
        (*s)->ch = *(str + *indexer);
        (*s)->node = (struct linkedList *) malloc(sizeof(struct linkedList));
        ++*indexer;
        addTolinkedList(str, &(*s)->node, indexer);
    }
}
char * combineWithNoSpaces(int argc, char *argv[]) {
    int i, j;
    int count = 0;
    int memory = 0;
    char *str;
    for (i = 1; i < argc; i++) {
        for (j = 0; j < strlen(argv[i]); j++) {
            ++memory;
        }
    }
    str = (char *) malloc(memory * sizeof(char) + 1);
    for (i = 1; i < argc; i++) {
        for (j = 0; j < strlen(argv[i]); j++) {
            *(str + count) = argv[i][j];
            ++count;
        }
    }
    return str;
}
void printMenu(void) {
    printf("\n\n"
            "1. print input arguments (no spaces)\n"
            "2. remove first character\n"
            "3. remove vowels\n"
            "4. is the linked list empty?\n"
            "5. exit program\n"
            "Enter your choice>");
}

输出的屏幕截图为:

对于参数柠檬


对于参数aeiou

The screen shot for output is :
For argument lemon
For argument aeiou

推荐答案

这段代码对我很满意。它几乎是一个MCVE(最小,完整,可验证的示例

This code works to my satisfaction. It is more nearly an MCVE (Minimal, Complete, Verifiable Example.

我打电话给程序 rv19 。当这样运行时,它显示的输出如下:

I called the program rv19. When run like this, it gives the output shown:

$ rv19 apple
[apple]
[ppl]
$ rv19 nutmeg
[nutmeg]
[ntmg]
$ rv19 ply
[ply]
[ply]
$ rv19 aeiou
[aeiou]
[]
$ rv19 aardvark abstemiously facetiously aeiou minions lampoon shampoo
[aardvarkabstemiouslyfacetiouslyaeiouminionslampoonshampoo]
[rdvrkbstmslyfctslymnnslmpnshmp]
$ 

代码( rv19.c ):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct linkedList
{
    char ch;
    struct linkedList *node;
};

char *combineWithNoSpaces(int, char *[]);
void addTolinkedList(char *, struct linkedList **, int *);
void printLinkedList(struct linkedList **);
struct linkedList *locate(struct linkedList **);
int delHead(struct linkedList **);
void removeVowels(struct linkedList **);
void freeLinkedList(struct linkedList *);

int main(int argc, char *argv[])
{
    int indexer = 0;
    struct linkedList *s;
    char *string;
    if (argc == 1)
    {
        printf("Parse a sentence.  Usage: %s word [word ...]\n", argv[0]);
    }
    else
    {
        s = (struct linkedList *) malloc(sizeof(struct linkedList));
        printf("s = %p\n", (void *)s);
        string = combineWithNoSpaces(argc, argv);
        addTolinkedList(string, &s, &indexer);
        printLinkedList(&s);
        removeVowels(&s);
        printLinkedList(&s);
        printf("s = %p\n", (void *)s);
        freeLinkedList(s);
        free(string);
    }
    return 0;
}

static inline int isvowel(char c)
{
    return(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
           c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
}

struct linkedList *locate(struct linkedList **s)
{
    if ((*s)->node == NULL)
        return NULL;
    if (isvowel((*s)->node->ch))
    {
        return *s;
    }
    else if ((*s)->node == NULL)
    {
        return NULL;
    }
    else
        return locate(&((*s)->node));
}

void removeVowels(struct linkedList **s)
{
    struct linkedList *temp, *tag;
    /* Remove leading vowels */
    while ((*s) != NULL && isvowel((*s)->ch))
    {
        //printf("Remove leading '%c'\n", (*s)->ch);
        struct linkedList *ts = *s;
        delHead(&ts);
        *s = ts;
    }
    struct linkedList *n = *s;
    while (n != NULL && (tag = locate(&n)) != NULL)
    {
        /* Remove multiple embedded or trailing vowels */
       while (tag->node != NULL && isvowel(tag->node->ch))
        {
            temp = tag->node;
            tag->node = tag->node->node;
            free(temp);
        }
        n = tag->node;
    }
}

int delHead(struct linkedList **s)
{
    struct linkedList *temp;
    if ((*s) == NULL)
        return 0;
    else
    {
        temp = (*s)->node;
        free(*s);
        *s = temp;
        return 1;
    }
}

void printLinkedList(struct linkedList **s)
{
    struct linkedList *n = *s;
    putchar('[');
    while (n != NULL)
    {
        putchar(n->ch);
        n = n->node;
    }
    putchar(']');
    putchar('\n');
}

void addTolinkedList(char *str, struct linkedList **s, int *indexer)
{
    if (*indexer == (int)strlen(str))
    {
        free(*s);
        *s = NULL;
    }
    else
    {
        (*s)->ch = *(str + *indexer);
        (*s)->node = (struct linkedList *) malloc(sizeof(struct linkedList));
        ++*indexer;
        addTolinkedList(str, &(*s)->node, indexer);
    }
}

char *combineWithNoSpaces(int argc, char *argv[])
{
    int argl[argc+1];
    int memory = 0;
    for (int i = 1; i < argc; i++)
    {
        argl[i] = strlen(argv[i]);
        memory += argl[i];
    }
    char *str = (char *) malloc(memory + 1);
    char *base = str;
    for (int i = 1; i < argc; i++)
    {
        strcpy(base, argv[i]);
        base += argl[i];
    }
    return str;
}

void freeLinkedList(struct linkedList *node)
{
    while (node != NULL)
    {
        struct linkedList *next = node->node;
        free(node);
        node = next;
    }
}

这仍然不尽如人意。我改变了打印,以便在开始和结束输出之后得到一个标记;更容易看到不必要的空白和其他类似的字符。现在是迭代的我也将界面更改为函数,所以它需要一个 struct linkedList * 而不是一个 struct linkedList ** removeVowels()中的代码很棘手;它重复地去除重复的初始元音;它重复地在非元音之后去除重复的元音。 locate()函数现在返回一个指向下一个节点中有元音的非元音节点的指针。该代码释放字符串和列表(使用新功能 freeLinkedList()来释放列表。

This is still not as polished as it could be. I changed the printing so as to get a marker before the start and after the end of the output; it is easier to see unwanted blanks and other characters like that. It's now iterative. I'd change the interface to the function, too, so it takes a struct linkedList * instead of a struct linkedList **. The code in removeVowels() is tricky; it iterates to remove repeated initial vowels; it iterates to remove repeated vowels after a non-vowel. The locate() function now returns a pointer to a non-vowel node that has a vowel in the next node. This code frees both the string and the list (using a new function, freeLinkedList() to free the list).

我已经检查了几个调试版本的 malloc(),它似乎是无泄漏和无腐败的。

I've checked it with a couple of debugging versions of malloc(), and it seems to be leak free and corruption free.

我还没有运行 valgrind ,因为在macOS Sierra 10.12上构建之后我无法正常运行:

I still haven't run it with valgrind because I can't get it to run properly after building it on macOS Sierra 10.12:

valgrind: mmap-FIXED(0x0, 253952) failed in UME (load_segment1) with error 12 (Cannot allocate memory).

这是从SVN下载的最新代码(修订版本16097)。

This was with the latest code downloaded from SVN (revision 16097).

这篇关于无法从单链表中删除元音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆