2010-05-28 11 views
5

लागू करने से पहले, बस सभी को यह बताने दें कि यह मजेदार है और मैंने अपने सभी कोड को अभी तक पोस्ट किया है; चीजें ठीक/लागू होने के रूप में अधिक पोस्ट करेंगे), लंबी पोस्ट के लिए खेद है!कुछ भी पूछने से पहले एक स्क्रैबल सॉल्वर

मेरे यहां दो प्रश्न हैं और मैं नीचे अपना पूरा कोड पोस्ट करूंगा।

  1. मैं क्यों जब एक ही पत्र से कुछ के साथ 12+ पत्र inputting, मैं कई डुप्लिकेट मेरे 'स्वीकार किए जाते हैं' पूर्णांक के रूप में जगह डुप्लिकेट से बचने के लिए किया जाता है हो रही है यह पता लगाने की नहीं कर पा रहे (अधिकांश भाग के लिए काम करता है);
  2. को 26 अक्षरों और एक एनएक्सएन बोर्ड (पहले से भरने वाले कुछ अक्षर होने) के इनपुट दिए गए हैं, वैध धब्बे में फिट होने वाले सभी संभावित शब्द संयोजनों को आउटपुट करें। इस बारे में कोई सलाह है कि इस बारे में कैसे जाना है (बोर्ड 1 अक्षर के लिए प्रत्येक में 2-डी सरणी 1 चार स्थान होगा)

अभी यह केवल एक पाठ आधारित प्रोग्राम है जो 26 अक्षरों और आउटपुट को स्वीकार करता है 200K शब्द + शब्दकोश से सभी वैध शब्द यहां पोस्ट:

http://www.calvin.edu/~rpruim/scrabble/ospd3.txt

नीचे सी कार्यक्रम शब्दकोश की आवश्यकता है 26 सभी शब्दों प्रत्येक फ़ाइल में प्रत्येक अक्षर (फ़ाइल में सभी एक शब्द के साथ शुरुआत युक्त फ़ाइलों में कटा हुआ जा करने के लिए 'ए' आदि ...) perl ऐसा करने के लिए नीचे पोस्ट किया गया है।

पद खोजक (ग):

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

#define NUM_CHARS 26 
#define MAX_WORD_LEN 20 
#define WORDS_PER_LINE 12 

/* Character link structure */ 
typedef struct char_link 
{ 
    struct char_link **cl; /* All of this links possible next characters */ 
    short eow;    /* END OF WORD (means this is the last letter of a valid word */ 
} CHARLINK; 
/* Global found word count, used for printing '\n' char. */ 
unsigned short gwc = 0; 
CHARLINK * _init_link(CHARLINK **link) 
{ 
    short i; 
    (*link)->cl = (CHARLINK **) malloc(NUM_CHARS * sizeof(CHARLINK *)); 
    for (i = 0; i < NUM_CHARS; i++) 
     (*link)->cl[i] = NULL; 
    (*link)->eow = 0; 
    return (*link); 
} 

void _build_char_link(CHARLINK *link) 
{ 
    FILE *fp; 
    char *ptr, file[2]; 
    CHARLINK *current_link = NULL; 
    char line_buffer[MAX_WORD_LEN]; 
    unsigned short size = 0; 
    static short letter_index = 0; 
    int current_letter = 0; 

    sprintf(file, "%c", letter_index + 'a'); 
    current_link = _init_link(&link); 

    if (fp = fopen(file, "r")) 
    { 
     while (fgets(line_buffer, MAX_WORD_LEN, fp) > 0) 
     { 
      /* Skip letter_index */ 
      ptr = line_buffer + 1; 

      while(*ptr && (*ptr != '\n' && *ptr != '\r')) 
      { 
       current_letter = (int)(*ptr - 'a'); 

       /* Create and jump to new link */ 
       if (!current_link->cl[current_letter]) 
       { 
        current_link->cl[current_letter] = (CHARLINK *) malloc (sizeof(CHARLINK)); 
        current_link = _init_link(&current_link->cl[current_letter]); 
       } 
       /* Jump to existing link */ 
       else 
        current_link = current_link->cl[current_letter]; 

       ptr++; 
      } 

      current_link->eow = 1; 
      /* Reset our current_link pointer to the letter_index link */ 
      current_link = link; 
     } 
     fclose(fp); 
    } 
    else 
     printf("Warning: Couldn't import words for letter: %s\n", file); 

    letter_index++; 
} 

void _draw_tree(CHARLINK *link, short letter, short depth) 
{ 
    short i, tmp; 

    if (!depth) 
    { 
     printf("Data for letter %c\n", letter + 'a'); 
     printf("%c\n", letter + 'a'); 
    } 

    for (i = 0; i < NUM_CHARS; i++) 
    { 
     if (link->cl[i]) 
     { 
      tmp = depth; 
      while (tmp-- >= 0) 
       printf("\t"); 
      printf("%c(%d)\n", i + 'a', link->cl[i]->eow); 
      _draw_tree(link->cl[i], letter, depth + 1); 
     } 
    } 
} 

void _get_possible_words(CHARLINK *link, char *prefix, char *letters, unsigned int input_len, unsigned int depth) 
{ 
    short i, len, j; 
    unsigned int attempted = 0x00000000; 

    if (link->eow) 
    { 
     printf("\t%s", prefix); 
     if (++gwc == WORDS_PER_LINE) 
     { 
      printf("\n"); 
      gwc = 0; 
     } 
    } 

    len = strlen(prefix); 
    for (i = 0; i < input_len; i++) 
    { 
     if (letters[i]) 
     { 
      j = (1 << (letters[i] - 'a')); 
      if (!(j & attempted) && link->cl[letters[i] - 'a']) 
      { 
       prefix[len] = letters[i]; 
       letters[i] = '\0'; 
       _get_possible_words(link->cl[prefix[len] - 'a'], prefix, letters, input_len, depth + 1); 
       letters[i] = prefix[len]; 
       prefix[len] = '\0'; 
      } 
      attempted |= j; 
     } 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    short i; 
    /* 26 link structures for a-z */ 
    CHARLINK root_nodes[NUM_CHARS]; 
    printf("Building structures "); 
    for (i = 0; i < NUM_CHARS; i++) 
    { 
     _build_char_link(&root_nodes[i]); 
     printf(". "); 
    } 
    printf("Done!\n"); 
    /* Debug, what do our trees look like? */ 
    //for (i = 0; i < NUM_CHARS; i++) 
    // _draw_tree(&root_nodes[i], i, 0); 

    for(;;) 
    { 
     short input_len = 0; 
     unsigned int j = 0, attempted = 0x00000000; 
     char input[26] = {0}; 
     char letters[26] = {0}; 
     char prefix[26] = {0}; 
     printf("Enter letters ('0' to exit): "); 
     gets(input); /* Yay buffer overflow */ 
     if (input[0] == '0') break; 
     sprintf(letters, "%s", input); 
     input_len = strlen(input); 
     for (i = 0; i < input_len; i++) 
     { 
      j = (1 << (input[i] - 'a')); 
      if (!(j & attempted)) 
      { 
       prefix[0] = input[i]; 
       letters[i] = '\0'; 
       _get_possible_words(&root_nodes[prefix[0] - 'a'], prefix, letters, input_len, 1); 
       letters[i] = input[i]; 
       attempted |= j; 
      } 
     } 
     printf("\n"); 
    } 

    return 255; 
} 

फ़ाइल विभाजन (पर्ल):

#!/usr/bin/perl 
open(FH, "< words.txt"); 
my %w = map { $_ => {} } 'a'..'z'; 
while (<FH>) 
{ 
    s/\s+$//; 
    $w{lc $1}->{lc $_} = 1 if /^(\w)/; 
} 

foreach my $l (keys %w) 
{ 
    open (OUT, "> $l"); 
    foreach my $a (keys %{$w{$l}}) 
    { 
     print OUT "$a\n"; 
    } 
    close OUT; 

} 
+1

यदि यह मजेदार है, तो आप इसे अपने लिए समझने की कोशिश क्यों नहीं करते? –

+10

कोई भी व्यक्ति जो यहां प्रश्न पोस्ट नहीं करता है, वह खुद को समझता है? यदि आप इसे देखना नहीं चाहते हैं तो नहीं। – user318747

+0

चूंकि आपने बफर ओवरफ़्लो को बुलाया है, और चूंकि आपके पास कुछ "मजेदार" है: पी * fgets * का उल्लेख करने के बजाय पी * मैं आपको इस भाषा में एक नई भाषा के रूप में सीखने के लिए इंगित करूंगा (जो लोग मॉनीटर करते हैं एस पर टैग को पसंद नहीं है, लेकिन व्हाटवा): http://www2.research.att.com/~bs/new_learning.pdf – HostileFork

उत्तर

5

बस कुछ अपने पर्ल पर विचार।

बड़े हैश प्रारंभ करने का कोई कारण नहीं है। आप इस के साथ एक पंक्ति में प्रारंभ कर सकते हैं:

my %w = map { $_ => {} } 'a'..'z'; 

लेकिन वहाँ वास्तव में init के लिए, पर्ल आप के लिए हैश refs autovivify होगा जब आप कहते हैं कोई कारण नहीं है:

$w{$1}{$_} = 1 if /^(\w)/; 

लेकिन आप एक है त्रुटि, यदि कोई शब्द कैपिटल अक्षर से शुरू होता है, तो यह गलत कुंजी में जाएगा। यदि आप इस तरह की त्रुटियों को पकड़ना चाहते हैं, तो आप अपने हैश में नई कुंजी जोड़ने के लिए हैश :: यूटिल के lock_keys का उपयोग कर सकते हैं। बग को ठीक करने के लिए, सही केस को मजबूर करने के लिए lc या uc का उपयोग करके अपने शब्दों को सामान्यीकृत करें।

आपके पास अपने पर्ल के साथ कुछ और स्टाइलिस्ट समस्याएं हैं। इसके अलावा, चूंकि आप (संभवतः) बड़ी फ़ाइलों के साथ काम कर रहे हैं, तो सभी शब्दों को स्मृति में क्यों रखें?

#!/usr/bin/perl 
use strict; 
use warnings; 

use IO::Handle; 

open my $fh, '<', $wordlist_path 
    or die "Error opening word list '$wordlist' - $!\n"; 

# Open a handle for each target file.  
my %handle = map { 
    open my $fh, '>', $_ 
     or die "Error opening sublist $_ - $!\n"; 
    $_ => $fh; 
} 'a'..'z'; 

while(my $word = <$fh>) { 

    $word = clean_word($word); 

    my $first_letter = substr $word, 0, 1; 

    $handle{$first_letter}->print("$word\n"); 
} 

sub clean_word { 
    my $word = shift; 

    chomp $word; 
    $word = lc $word; 

    $word =~ s/^\s*//; 
    $word =~ s/\s*$//; 

    return $word; 
} 
+2

'$ शब्द = ~ एस/^ \ एस + //; 'अधिक समझदार है। अन्यथा आप संभावित रूप से कुछ भी प्रतिस्थापित नहीं कर रहे हैं, उम, कुछ भी नहीं। – Zaid

संबंधित मुद्दे