Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

写惯GCC dialect的同志们当心了:strdup不支持(只能用strcpy),strdup交上去没有compiler error但是会WA

Posted by KevinSayHi at 2013-04-08 12:38:09 on Problem 1035 and last updated at 2013-04-08 12:42:56
POJ所谓的G++编译器(为了C99我总是把C代码提交到G++)居然不支持strdup,而且编译不报错,显示WA(这不坑爹吗,好在我眼明手快怀疑到是编译器问题;万一我debug不就冤死了)。

具体情形如下。在最下面可以看到我使用strdup的原程序(我习惯文件读入输出,所以交给POJ之前要改成屏幕读入输出),此程序WA。
接下来我做了一个简单修改,把strdup改成了fixed length的strcpy(没高兴malloc+strcpy),以下是git的commit summary:

--- a/spellcheck.c
+++ b/spellcheck.c
@@ -17,7 +17,7 @@
 #define MAX_NUM_CORRECTIONS 1000
 
 typedef struct {
-    char *word;
+    char word[MAX_WORD_LENGTH + 1];
     size_t len;
 } entry_t;
 
@@ -38,7 +38,7 @@ int main(int argc, const char *argv[]) {
         if (buf[0] == '#') {
             break;
         }
-        dict[dictSize].word = strdup(buf);
+        strcpy(dict[dictSize].word, buf);
         dict[dictSize].len = strlen(buf);
         dictSize++;
     }
@@ -50,7 +50,7 @@ int main(int argc, const char *argv[]) {
             break;
         }
         entry_t w;
-        w.word = strdup(buf);
+        strcpy(w.word, buf);
         w.len = strlen(buf);
 
         int corrections[MAX_NUM_CORRECTIONS];
可见只修改了三行,把variable length变成了fixed length,把两个strdup变成了strcpy。提交立A。

结论:被POJ破编译器问题坑了不知多少次了(什么C++找不到stdbool.h,G++/GCC一用double就WA)神马的,见怪不怪了。POJ上WA的程序debug之前千万考虑一下会不会是编译器问题。另外,POJ就不能给个详细点儿的编译器报告么,把我们都当dummy么。。。

PS. 欢迎大家测试,也有可能是我水平太低写得有问题。
PPS. 这题如果一开始就用fixed length就没什么问题了。但是real world programming不比OJ,能省则省。好习惯要紧,1A浮云。



原程序:
/**
 * spellcheck.c
 * POJ 1035
 * Created by ************ on 04/07/2013.
 * --------------------------------------
 * Brute force.
 */

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

#define MAX_NUM_ENTRIES 10000
#define MAX_WORD_LENGTH 15
#define MAX_NUM_CORRECTIONS 1000

typedef struct {
    char *word;
    size_t len;
} entry_t;

static inline bool replaceable(entry_t w1, entry_t w2);
static inline bool deletable(entry_t w1, entry_t w2);
static inline bool insertable(entry_t w1, entry_t w2);

int main(int argc, const char *argv[]) {
    FILE *in = fopen("spellcheck.in", "r");
    FILE *out = fopen("spellcheck.out", "w");

    // read dictionary
    entry_t dict[MAX_NUM_ENTRIES];
    int dictSize = 0;
    while (true) {
        char buf[MAX_WORD_LENGTH + 1];
        fscanf(in, "%s\n", buf);
        if (buf[0] == '#') {
            break;
        }
        dict[dictSize].word = strdup(buf);
        dict[dictSize].len = strlen(buf);
        dictSize++;
    }
    // spell check
    while (true) {
        char buf[MAX_WORD_LENGTH + 1];
        fscanf(in, "%s\n", buf);
        if (buf[0] == '#') {
            break;
        }
        entry_t w;
        w.word = strdup(buf);
        w.len = strlen(buf);

        int corrections[MAX_NUM_CORRECTIONS];
        int nCorrections = 0;
        bool isCorrect = false;
        for (int i = 0; i < dictSize; i++) {
            if (strcmp(w.word, dict[i].word) == 0) {
                // correct, immediately acknowledge
                isCorrect = true;
                fprintf(out, "%s is correct\n", w.word);
                break;
            }
            if (replaceable(w, dict[i]) ||
                deletable(w, dict[i]) ||
                insertable(w, dict[i])) {
                // possible correction
                corrections[nCorrections++] = i;
            }
        }
        if (isCorrect) {
            continue;
        }
        // print corrections
        fprintf(out, "%s:", w.word);
        for (int i = 0; i < nCorrections; i++) {
            fprintf(out, " %s", dict[corrections[i]].word);
        }
        fputc('\n', out);
    }
    
    fclose(in);
    fclose(out);
    return 0;
}

static inline bool
replaceable(entry_t w1, entry_t w2) {
    if (w1.len != w2.len) {
        return false;
    }
    int diff = 0;
    for (char *i = w1.word, *j = w2.word;
         *i /* same length, one check is enough */; i++, j++) {
        if (*i != *j) {
            diff++;
        }
    }
    return (diff == 1);
}

static inline bool
deletable(entry_t w1, entry_t w2) {
    if (w1.len != w2.len + 1) {
        return false;
    }
    // search forward for prefix match
    size_t prefixMatch = 0;
    for (char *i = w1.word, *j = w2.word; *j; i++, j++) {
        if (*i == *j) {
            prefixMatch++;
        } else {
            break;
        }
    }
    // search backward for suffix match
    size_t suffixMatch = 0;
    for (char *i = w1.word + w1.len - 1, *j = w2.word + w2.len - 1;
         j >= w2.word; i--, j--) {
        if (*i == *j) {
            suffixMatch++;
        } else {
            break;
        }
    }
    return (prefixMatch + suffixMatch >= w2.len);
}

static inline bool
insertable(entry_t w1, entry_t w2) {
    return deletable(w2, w1);
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator