【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.18802

ファイルの出力について
投稿者---まさと(2004/12/19 11:01:27)


現在、ハッシュ法のプログラムを用いて、Excelにハッシュ表の各要素に格納されているデータ数を表示させるために、”heihoucoll997_900.xls”を用いています。Excelに出力されたファイルの画面で、以下のように表示されます。

/* --ハッシュ表の各要素のデータ数-- */
1 /*[745(例)]にデータが1つ格納されている*/
1
12
123 /*[748(例)]にデータが3つ格納されている*/
1
123456 /*[750(例)]にデータが6つ格納されている*/

つまり、末尾のノードまで各ノードの個数を数えてしまいます。目的としている、出力画面を以下のように行いたいのです。

/*目的としている出力画面*/
1 /*データが1つ格納されている*/
1
2 /*データが2つ格納されている*/
3 /*データが3つ格納されている*/
1
6   /*データが6つ格納されている*/

このように、末尾ノードだけを参照して、
各要素のノードのデータ数を出力するためには、
どのようにプログラムを改良すればいいのでしょうか?
/* --現在のプログラムソース-- */


/* ハッシュ法:チェイン法) */
/* ハッシュ関数:平方採中法(mid-square method) */

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

#define HashSize 997    /*ハッシュ表のサイズ(大きさ)   <<サイズを変更する>>  */

/*ハッシュ表に格納するデータを表す構造体*/
typedef struct cell{
    char name[20];    /*名前*/
    int collision;    /*衝突回数*/
    int datasum;        /*データ数*/
    struct cell *next;  /*次のセルへのポインタ*/
} Data;

Data *hashtable[HashSize];    /*ハッシュ表*/
FILE *fp;

void MakeHashTable(void);      /*ハッシュ表を初期化する*/
void Chaining(Data *, unsigned int);
unsigned int Hash(char *);    /*ハッシュ関数*/
void PrintAllData(void);        /*ハッシュ表の中身を出力*/
void FreeHashTable(void);      /*ハッシュ表を後始末*/

/*ハッシュ表を初期化する*/
void MakeHashTable()
{
    Data *temp;
    int i;
    
    /*ハッシュ表を初期化*/
    for(i=0; i<HashSize; i++)
        hashtable[i]=NULL;
        
    if((fp=fopen("word900.txt", "r"))==NULL){            /*  <<変更する>>  */
        printf("ファイルを開く事が出来ません。\n");
        exit(1);
    }
    
    for(;;){
        temp=(Data *)malloc(sizeof(Data));  /*大きさがDataバイトの領域を確保*/
        if(fscanf(fp, "%s", temp->name)!=EOF){
            temp->next=NULL;
            Chaining(temp, Hash(temp->name));
        }
        else{
            free(temp);
            break;
        }
    }
}

void Chaining(Data *temp, unsigned int f)
{
    Data *s;
    int no=1;
    temp->collision=0;
    temp->datasum=1;
    
    if(hashtable[f]==NULL){
        hashtable[f]=temp;
    }
    else{
        s=hashtable[f];
        while(s->next)
            s=s->next;
            no++;
        s->next=temp;
        s->next->collision=s->collision+1;
        s->next->datasum=s->datasum+1;
    }
}

/*ハッシュ関数(平方採中法)*/
unsigned int Hash(char *buf)
{
  unsigned int value;
  for(value=0; *buf!='\0'; buf++)
    value=*buf+value*11;
  return ((value*value)/HashSize)%HashSize;
}

/*ハッシュ表の中身を出力*/
void PrintAllData(void)
{
    Data *s;
    FILE *datafp;
    FILE *fp;
    int i;

    datafp=fopen("chain(mid-square)997_900.txt", "w");  /*全データ&衝突回数を新規ファイルに出力 <<ファイル名を変更する>> */
    fp=fopen("heihoucoll997_900.xls", "w"); /*衝突回数を新規ファイルに出力 <<ファイル名を変更する>> */
    for(i=0; i<HashSize; i++){
        printf("[%d]\t", i);
        s=hashtable[i];
        while(s){
            printf("%-16s:%d回衝突\t->", s->name, s->collision);
            fprintf(datafp, "[%d]%-16s:%d回衝突\t->", i, s->name, s->collision);
            fprintf(fp, "%d", s->datasum);
            s=s->next;
        }
        printf("NULL\n");
        fprintf(datafp, "[%d]NULL\n", i);
        fprintf(fp, "\n");
    }
    fclose(datafp);
    fclose(fp);
}


/*ハッシュ表を後始末*/
void FreeHashTable(void)
{
    int i;
    Data *s, *t;

    for(i=0; i<HashSize; i++){
        s=hashtable[i];
        while(s){
            t=s->next;
            free(s);
            s=t;
        }
    }
}

int main(void)
{
    MakeHashTable();
    PrintAllData();
    FreeHashTable();
    fclose(fp);
    return(0);
}






この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイルの出力について 18803 まさと 2004/12/19 11:02:32


No.18803

Re:ファイルの出力について
投稿者---まさと(2004/12/19 11:02:32)


ハッシュ表に読み込む(格納する)データはword.txtとし、
データの中身は、以下に記します。

<word.txt>
rejoice
duplicate
lantern
shed
chop
livestock
network
milestone
advocate
visibility
label
sociobiology
cram
synchronize
interconnect
empirical
oral
discourse
scorn
overall
incongruous
counterpart
commentary
sermon
ethnic
linguistics
totality
reassure
banal
fluently
wit
nuance
stack
discard
quotation
decree
prophecy
generalize
stick
insecure
magically
foresee
intuition
tone
botany
cynical
popularity
kingdom
turn
dominance
combat
warfare
nephew
niece
company
probe
arouse
clumsy
mastery
heed
sink
companion
liable
inspire
reverence
snob
manhood
purse
sow
unaffected
glossy
depict
breast
bundle
dental
rubber
clutch
premature
clinic
threshold
ritual
undeniable
nonetheless
pervasive
exotic
avenge
witch
devour
cast
humiliate
subdue
nightmare
apprehend
timid
scoff
nonsense
myriad
blossom
slip
dimension
passionate
deed
fairy
long
entitle
flight
chariot
laser
beam
drug
deplore
childish
acute
dwarf
sight
stature
discern
heritage
collaborate
renew
domain
capture
colleague
recruit
personality
score
aspire
barometer
insulate
inn
arrange
bargain
standardize
crack
etiquette
thrill
cape
acquaintance
rim
explore
chase
pioneer
yearn
dig
pole
whistle
rhythmic
punctuate
agenda
interval
intricate
solemn
cumulative
climax
persevere
integrity
denounce
illustrate
hinder
foster
valley
monster
embody
docile
domesticate
streak
solitary
herd
inconclusive
inscription
captivity
cemetery
coincide
preoccupy
industrialization
criterion
backward
abreast
stagger
unparalleled
stationary
tropical
ragged
shiver
amply
flaw
uninhabitable
chimney
freeze
awkward
ancestry
melancholy
twilight
brute
prehistoric
tip
spear
equate
personify
genesis
flood
ascribe
designate
poison
suspect
pledge
amity
acidity
palatable
summary
twist
duke
dedicate
omit
horizontal
column
dignity
serene
adorn
conform
barbarian
outward
saint
interior
exemplify
carve
monument
truthfulness
aesthetic
susceptible
knee
blind
astray
cease
household
reputability
unattractive
indignant
sustain
alcohol
liquor
beverage
intoxicate
addiction
seal
adhere
consultation
keenly
widespread
envelope
paradox
pollution
radioactive
minute
agent
augment
fossil
carbon
emission
discharge
trial
suppress
constrict
fuel
locate
acre
appalling
catastrophe
capital
charitable
card
impure
mineral
vaporize
confirm
unidentified
hover
quote
dispatch
modest
status
posture
prominent
colony
bear
socialist
totalitarian
scarcely
cell
incomparably
portrait
donor
understandably
historian
document
quarter
mine
stir
eccentric
contemplate
suicide
snatch
eventually
lap
hammer
dawn
recollect
soothe
ambulance
incessant
dampen
appetite
annual
soak
gloomy
rebuke
humility
admiration
secretary
divorce
ground
expire
communist
disapprove
corrupt
namely
incompatible
greediness
lament
ardent
contrive
arm
heir
invariably
unconventional
rent
beard
haunt
debt
award
will
estate
bankrupt
prompt
fury
rash
induce
vengeful
harbor
incommunicable
clarify
qualitative
restructure
stuff
central



この投稿にコメントする

削除パスワード

No.18807

Re:ファイルの出力について
投稿者---Hermit(2004/12/19 15:50:36)


いろいろ方法はありますが、

1、最後のデーターだけ出力するようにする。

2、データーを入れるとき、1,2,3.... でなく、...3,2,1 のように
  最初に総数が来るように設定して、最初のデーターだけ表示する。

3、データー数を入れる場所を別に確保する

1、2、3の、どれかかな?

まあ、やり方は考えてみてください。


この投稿にコメントする

削除パスワード

No.18808

Re:ファイルの出力について
投稿者---まさと(2004/12/19 17:51:23)


>いろいろ方法はありますが、
>
>1、最後のデーターだけ出力するようにする。
>
>2、データーを入れるとき、1,2,3.... でなく、...3,2,1 のように
>  最初に総数が来るように設定して、最初のデーターだけ表示する。
>
>3、データー数を入れる場所を別に確保する
>
>1、2、3の、どれかかな?
>
>まあ、やり方は考えてみてください。

早速の、ご返信ありがとう御座います。
1番の方法で、「ハッシュ表の中身を出力のvoid PrintAllData(void)」
のプログラムを訂正しておりますが、エラーが出現し、
目的のデータが出力できません・・・。


この投稿にコメントする

削除パスワード

No.18809

Re:ファイルの出力について
投稿者---まさと(2004/12/19 18:33:20)


新たに、プログラムを作成してみましたが、
ぜんぜん、出来なく、余計こんがらがってしまいました。
御教授お願い致します。

/*新たに作成した出力ソース*/
/*ハッシュ表の中身を出力*/
void PrintAllData(void)
{
    Data *s;
    
    int i;
    int table[TableSize];   /*追加*/

    for(i=0; i<TableSize; i++)
        table[i]=0;
    for(i=0; i<HashSize; i++){
        Data *s=hashtable[i];
        int n=0;
        if(s!=NULL){
            for(; s!=NULL; s=s->next)
                n++;
        }
        if(n<TableSize){
            table[n]++;
        }
        else{
            fprintf(stderr, "エラー%d\n", n);
        }
    }
    for(i=0; i<TableSize; i++){
        if(!(i%8))
            putchar('\n');
            printf("%d:%d", i, table[i]);
    }
}


/*前の出力ソース*/
/*ハッシュ表の中身を出力*/
void PrintAllData(void)
{
    Data *s;
    FILE *datafp;
    FILE *fp;
    int i;

    datafp=fopen("g.txt", "w"); /*全データ&衝突回数を新規ファイルに出力 <<ファイル名を変更する>> */
    fp=fopen("h.xls", "w");  /*衝突回数を新規ファイルに出力 <<ファイル名を変更する>> */
    for(i=0; i<HashSize; i++){
        printf("[%d]\t", i);
        s=hashtable[i];
        while(s){
            printf("%-16s:%d回衝突\t->", s->name, s->collision);
            fprintf(datafp, "[%d]%-16s:%d回衝突\t->", i, s->name, s->collision);
            fprintf(fp, "%d->", s->datasum);        /*fprintf(fp, "[%d]%d回衝突(データ数%d) ->", i, s->collision, s->datasum);*/
            s=s->next;
        }
        printf("NULL\n");
        fprintf(datafp, "[%d]NULL\n", i);
        fprintf(fp, "\n");
    } 
    fclose(datafp);
    fclose(fp);
}



この投稿にコメントする

削除パスワード

No.18811

Re:ファイルの出力について
投稿者---Hermit(2004/12/19 22:44:44)


新しいソースの方、何がやりたいか全くわからないのだけど・・・
前のソースの方で追加

    for(i=0; i<HashSize; i++){
        int no = 0; //追加
        printf("[%d]\t", i);
        s=hashtable[i];
        while(s){
            printf("%-16s:%d回衝突\t->", s->name, s->collision);
            fprintf(datafp, "[%d]%-16s:%d回衝突\t->", i, s->name, s->collision);
//  削除          fprintf(fp, "%d->", s->datasum);        
            no = s->datasum; //追加
            s=s->next;
        }
        printf("NULL\n");
        fprintf(datafp, "[%d]NULL\n", i);
        fprintf(fp, no ? "%d\n" : "\n", no);// 変更

くらいでいいんじゃないかな(未確認)




この投稿にコメントする

削除パスワード

No.18820

Re:ファイルの出力について
投稿者---まさと(2004/12/20 10:34:23)


><pre>新しいソースの方、何がやりたいか全くわからないのだけど・・・
前のソースの方で追加

for(i=0; i<HashSize; i++){
int no = 0; //追加
printf("[%d]\t", i);
s=hashtable[i];
while(s){
printf("%-16s:%d回衝突\t->", s->name, s->collision);
fprintf(datafp, "[%d]%-16s:%d回衝突\t->", i, s->name, s->collision);
// 削除 fprintf(fp, "%d->", s->datasum);
no = s->datasum; //追加
s=s->next;
}
printf("NULL\n");
fprintf(datafp, "[%d]NULL\n", i);
fprintf(fp, no ? "%d\n" : "\n", no);// 変更

くらいでいいんじゃないかな(未確認)

</pre>

Hermit様、ご返信遅れまして申し訳御座いません。
無事、目的の最後のデータ数だけを出力できました。
ご迷惑をおかけして申し訳御座いませんでした。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧