מחפש אלגוריתם - ANSI C - עמוד 3 - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

מחפש אלגוריתם - ANSI C


iem

Recommended Posts

תבדוק את כל מקרי הקצה. קודם כל תבדוק שהדוגמאות שבתרגיל עובדות, וחוץ מזה תנסה כל מיני דברים אחרים (מה קורה אם הקלט מכיל ערבוב של אותיות קטנות וגדולות? שתי נקודות ברצף? שתי מרכאות ברצף? תווים שאינם אותיות או מספרים, גם באמצע המשפט, גם בתחילתו, וגם בתוך מרכאות? וכד').

ועוד הערה קטנה - התעלמת מסעיף 5.

קישור לתוכן
שתף באתרים אחרים

  • תגובות 42
  • נוצר
  • תגובה אחרונה

עכשיו אפשר להגיד שהתוכנית הושלמה ? :-\


#include <stdio.h>

#define TRUE 1
#define FALSE 0

int main (void){

char ch;
int dot_flag=TRUE;
int geresh_flag=FLASE;

while (ch=getchar() != EOF){
if ((ch>='0')&&(ch<='9'))
{
continue;
}
if (ch=='.')
{
dot_flag=TRUE;
}
else if (ch=='"')
{
if (geresh_flag==TRUE)
{
geresh_flag=FALSE;
}
else geresh_flag=TRUE;


}
else if ((ch>='a')&&(ch<='z')||(ch>='A')&&(ch<='Z'))
{
if(dot_flag==TRUE)
{
ch=ch&223;
dot_flag=FALSE;
}
else if (geresh_flag==TRUE)
{
ch=ch&223;
}
else ch=ch&223;



}
putchar(ch);
if (ch=='\n')
{
putchar(ch);
}
}
return 0;
}

קישור לתוכן
שתף באתרים אחרים

האמת שהדבר היחיד שהיא עושה זה להתעלם ממספרים ולהדפיס לי הכל באותיות גדולות....

אגב אם אני לוחץ על אנטר לשורה חדשה הוא אמור לתת לי פלט ישר עוד לפני שאני לוחץ על כפתור ה-stop ב-console של ה-eclipse ??

[attachment deleted by admin]

קישור לתוכן
שתף באתרים אחרים

טוב, עכשיו שאני מניח שכבר התרגיל גמור, אני אסביר איך אני הייתי פותר את התרגיל, שלב אחר שלב. כמו שכבר ציינתי קודם, לתרגיל הזה יש חלוקה מאוד טבעית לשלבים - שלב ראשון הוא כתיבת תכנית שרק קוראת קלט ומדפיסה אותו, ואז חמשת הסעיפים בתרגיל הם חמשת השלבים הנוספים (כל שלב הוא למעשה "פיצ'ר"). חשוב לומר שהרבה פעמים בעולם התוכנה האמיתי ככה באמת נראה פיתוח תוכנה - מתחילים ממשהו בסיסי, וכל פעם מוסיפים עוד ועוד "פיצ'רים".

אחד הדברים החשובים כאן הוא מה שנקרא "continuous integration" - אחרי כל שלב אנחנו דואגים לקמפל ולהריץ את התכנית, ולוודא שהיא עושה בדיוק מה שמצופה ממנה - כלומר, מבצעת את כל הפיצ'רים שמימשנו עד כה. חשוב לדאוג שכשאנחנו מממשים פיצ'ר מתקדם, אנחנו דואגים לבדוק שכל הפיצ'רים שמימשנו עד כה עדיין עובדים.

עכשיו נתחיל. בשלב הראשון (או ליתר דיוק, שלב 0) נרצה תכנית שרק קוראת מהקלט תווים ומדפיסה אותם. אני אכתוב פה את התכנית ואתן לקורא הנבון להבין בעצמו (תסלחו לי שאני משמיט את ה-include ואת המעטפת של ה-main, זה פשוט כדי לחסוך מקום):

  char ch;

while ((ch = getchar()) != EOF) {
putchar(ch);
}

כאמור, אחרי שלב זה יש לקמפל את התכנית ולהריץ אותה, ולוודא שהיא אכן מדפיסה בדיוק את הקלט שנזין לתוכה.

בשלב הבא נרצה לממש את סעיף 1 - בתחילת כל משפט, אם התו הראשון הוא אות אז להדפיס אות גדולה. נצטרך לעשות בשביל זה שני שינויים בקוד - שינוי אחד שיזהה מתי אנחנו בתחילת משפט (באמצעות נקודה), ושינוי שני שיידע לההפוך את האות הקטנה לגדולה, אם צריך:

  char ch;
int start_of_sentence = 1;

while ((ch = getchar()) != EOF) {
if (ch == '.') {
start_of_sentence = 1;
} else if (isalpha(ch)) {
if (start_of_sentence) {
ch = toupper(ch);
start_of_sentence = 0;
}
}

putchar(ch);
}

נקודות לציון:

א. בשורות 7-8 עשיתי if בתוך if. אמנם היה אפשר להחליף את זה ב-&&, אבל בשלבים הבאים בכל מקרה נצטרך להפריד את ה-if שוב.

ב. השתמשתי בפונקציות isalpha ו-toupper, אבל אם אסור להשתמש בפונקציות ספריה אז ניתן בקלות לממש אותן בעצמנו או להחליף אותן בבדיקה רגילה.

ג. המצב ההתחלתי של start_of_sentence הוא 1, כי תחילת הטקסט היא גם תחילת משפט.

כעת נממש את סעיף 2 - כל ביטוי בין גרשיים חייב להיכתב באותיות גדולות. כאן, בדיוק כמו בסעיף 1, צריך לבצע שני שינויים - אחד שיזהה מתי אנחנו בתוך גרשיים, ואחד שיבצע את השינוי באות בהתאם:

  char ch;
int start_of_sentence = 1;
int in_quotes = 0; /////////////

while ((ch = getchar()) != EOF) {
if (ch == '.') {
start_of_sentence = 1;
} else if (ch == '\"') { /////////////
in_quotes = !in_quotes; /////////////
} else if (isalpha(ch)) {
if (start_of_sentence || in_quotes) { /////////////
ch = toupper(ch);
start_of_sentence = 0;
}
}

putchar(ch);
}

נקודות לציון:

א. את השורות שהוספתי או שיניתי סימנתי ב-///////.

ב. הביטוי in_quotes = !in_quotes בדיוק הופך את הערך של in_quotes - אם הוא היה 0 אז הוא יהפוך ל-1, ואם הוא היה 1 אז הוא יהפוך ל-0.

ג. יש פה יתירות מסויימת - ב-if האחרון, אנחנו תמיד start_of_sentence = 0. באופן תיאורטי היינו צריכים לעשות את זה רק אם ערכו היה 1 - אבל זה היה גורר if מיותר או שכפול קוד, והתוצאה הסופית הייתה זהה.

בשלב 3 נרצה שכל שאר האותיות (אלו שלא בתוך גרשיים או בתחילת משפט) יומרו לאותיות קטנות. יש לזה שני פתרונות - אופציה אחת היא מראש להמיר את כל אותיות הקלט לקטנות, כך שזו למעשה היא ברירת המחדל. אופציה שנייה היא שהאותיות יומרו לקטנות רק אם הן לא הוגדלו - כלומר, באמצעות else. אני בחרתי באפשרות השנייה:

  char ch;
int start_of_sentence = 1;
int in_quotes = 0;

while ((ch = getchar()) != EOF) {
if (ch == '.') {
start_of_sentence = 1;
} else if (ch == '\"') {
in_quotes = !in_quotes;
} else if (isalpha(ch)) {
if (start_of_sentence || in_quotes) {
ch = toupper(ch);
start_of_sentence = 0;
} else { ////////////
ch = tolower(ch); ////////////
}
}

putchar(ch);
}

בשלב הבא נרצה להתעלם מספרות לחלוטין. גם לזה יש מספר פתרונות - דרך אחת היא למנוע את הדפסתן (ע"י הוספת תנאי לפני ה-putchar), ודרך שנייה היא מראש לא לטפל בהן ולעבור לטיפול בתו הבא, באמצעות continue. בחרתי בדרך השנייה:

  char ch;
int start_of_sentence = 1;
int in_quotes = 0;

while ((ch = getchar()) != EOF) {
if (isdigit(ch)) { /////////////
continue; /////////////
} else if (ch == '.') { /////////////
start_of_sentence = 1;
} else if (ch == '\"') {
in_quotes = !in_quotes;
} else if (isalpha(ch)) {
if (start_of_sentence || in_quotes) {
ch = toupper(ch);
start_of_sentence = 0;
} else {
ch = tolower(ch);
}
}

putchar(ch);
}

בשלב האחרון נשאר לדאוג שאם התו הוא ירידת שורה, אז נוסיף עוד ירידת שורה. זאת אפשר לבצע באמצעות תנאי פשוט:

  char ch;
int start_of_sentence = 1;
int in_quotes = 0;

while ((ch = getchar()) != EOF) {
if (isdigit(ch)) {
continue;
} else if (ch == '.') {
start_of_sentence = 1;
} else if (ch == '\"') {
in_quotes = !in_quotes;
} else if (isalpha(ch)) {
if (start_of_sentence || in_quotes) {
ch = toupper(ch);
start_of_sentence = 0;
} else {
ch = tolower(ch);
}
} else if (ch == '\n') { ////////////
putchar(ch); ////////////
} ////////////
putchar(ch);
}

כעת רק צריך לוודא שהתכנית אכן עובדת ומבצעת כל מה שהיא צריכה לבצע. כפי שציינתי קודם, באופן אופטימלי היינו צריכים להריץ את התכנית אחרי כל שלב כדי לוודא שהפיצ'ר החדש שהכנסנו עובד, ושלא "שברנו" את שאר התכנית.

קישור לתוכן
שתף באתרים אחרים

  • 2 שבועות מאוחר יותר...

היי יואב ;)

רק עכשיו יצא לי להיכנס (לא תיארתי לעצמי שתגיב אחרי יחסית הרבה זמן) הייתי בחו"ל.

הפנמתי את מה שרשמת, חבל שלא באמת הסבירו לנו ככה במדמ"ח באונ' (לפחות בקורסים שעשיתי עד כה).

תודה על ההשקעה !! :)

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.


×
  • צור חדש...