第三章配列と文字列


練習問題3-2単語の長さ(word)複数の単語を入力し、平均長さを出力します.単語には大文字と小文字しか含まれず、1つ以上のスペースで区切られています.
分析:本題の核心はどのように1つの単語を区別するかで、問題の中の情報から知っていて、単語の間はスペースで隔てられているので、scanf関数を使って文字列を読み込んでちょうど単語を区別することができます
コード:
#include "stdafx.h"
#include "string.h"
#define MAX 1024//          1024-1

int _tmain(int argc, _TCHAR* argv[])
{
	char buf[MAX];
	int cnt=0,len=0,tlen=0;
	while(scanf("%s",buf)==1){
	    len=strlen(buf);
	//	printf("len=%d
",len); tlen+=len; cnt++; } printf("%d %d %.2lf
",tlen,cnt,(double)tlen/cnt); return 0; }

練習問題3-3積の末3位(product)
いくつかの整数(正の整数、負の数、またはゼロ)を入力し、それらの積の最後の3桁を出力します.これらの整数には大文字からなる文字列が混入します.プログラムは無視してください.ヒント:scanf("%d")を実行するときに1つの文字列に入力してみてはどうですか.
分析:本題の核心は積の末三位である.本題では,演算に関与する整数の積が整数の表現範囲を超える可能性があるという小さな落とし穴があるが,最後の3桁は演算に参加する各整数の最後の3桁にのみ関係していることを知っているので,入力した整数を処理(その中の大きな字母を除去することを含む)し,その後,各整数に対して最後の3桁を演算に参加し,演算の結果も最後の3桁だけを取る.このように、この問題のアルゴリズムフレームワークは次のようになります.
while(cin>>a){
        a,
       a    ,
      product=product*a%1000;
}

コード:
#include "stdafx.h"
#include "string.h"

int parseStrToInt(char *buf)
{
    int a;//         
	int len,base;
	int i,j;
	len=strlen(buf);
	j=0;
	for(i=0;i<len;i++){
	    if(!(buf[i]>='A' && buf[i]<='Z')){
			    buf[j++]=buf[i];
	    } 
	}
	buf[j]='\0';
	len=strlen(buf);
	a=0;
	for(i=0;i<len;i++){
		base=1;
		for(j=0;j<len-i-1;j++){
			base*=10;
		}
		a+=base*(buf[i]-'0'+0);//             :buf[i]-'0'+0
	}
	//printf("a=%d
",a); return a; } int _tmain(int argc, _TCHAR* argv[]) { char buf[12]; int a,product=1; while(scanf("%s",buf)==1){ a=parseStrToInt(buf); a%=1000; product=(product*a)%1000; } printf("%d
",product); return 0; }

練習問題3-4計算機(calculator)プログラムを作成し、行にプラス記号、マイナス記号または乗算記号を含む式を読み込み、その値を出力します.この演算子は二元演算子であることを保証し、両方の演算数は100を超えない非負の整数です.演算数と演算子は隣接していてもよいし、1つ以上のスペース、TABで区切られていてもよいです.行の先頭と末尾にはスペースがあります.ヒント:選択適切な入力方法を選択すると、問題を簡略化できます.
分析:本題の核心は入力です.問題では適切な入力方式を選択すべきであることが明確に提案されており,scanf関数を用いて整数を入力すると,非整数に遭遇すると受け入れが停止することを知っている.そこでscanfを用いて2つの整数を受け入れ,演算子を個別に処理した.
コード:
#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
	int x,y;
	double result;
	char op;
	scanf("%d",&x);
	while(scanf("%c",&op)==1){
	  if((op=='+') || (op=='-') || (op=='*') || (op=='/'))
		  break;
	}
	scanf("%d",&y);
	switch(op){
	  case '+': result=x+y;break;
	  case '-': result=x-y;break;
	  case '/': result=(double)x/y;break;//    x,y      
	  case '*': result=x*y;break;
	}
	printf(op=='/' ? "%lf
":"%.0lf
",result); return 0; }

練習問題3-5回転(rotate)n*n文字マトリクスを入力し、左に90度回転して出力します.
解析:本題の核心は交換,すなわち行列の行列を交換することであるが,交換に注意する際の各行毎の列の開始はi,i,すなわち各行はi行目のi列から交換する.アルゴリズムも簡単です.マトリクスを取得します(ここではファイルからマトリクスを読み出します).2.回転します.3.印刷
コード#コード#
#include "stdafx.h"
#include "stdio.h"
#define MAX 10//      10   

void print(char buf[][MAX],int size)
{//  
	int i,j;
	int flag=0;
    for(i=0;i<size;i++){
		for(j=0;j<size;j++){
			printf(flag++ ? " %c":"%c",buf[i][j]);
		}
		flag=0;
		printf("
"); } } int input(char (*buf)[MAX],const char *fileName) {// , 0 char c; int i=0,j=0,cnt=0;//cnt FILE *fin=fopen(fileName,"rb");//data.in 10 , 10 , if(fin){ while(fscanf(fin,"%c",&c)==1){ if(c!='
' && c!=' '){ buf[i][j++]=c; } if(c=='
'){ i++; j=0; } } cnt=i+1; fclose(fin); return cnt; }else{ return 0; } } void rotate(char (*buf)[MAX],int size) {// int i,j; char tempC; for(i=0;i<size;i++){ for(j=i;j<size;j++){ tempC=buf[j][i]; buf[j][i]=buf[i][j]; buf[i][j]=tempC; } } } int _tmain(int argc, _TCHAR* argv[]) { char buf[MAX][MAX]; char c,tempC; int i=0,j=0,cnt=0;//cnt cnt=input(buf,"data.in"); if(cnt){ print(buf,cnt); printf("------------------------
"); rotate(buf,cnt); print(buf,cnt); }else{ printf(" data.in !
"); } return 0; }

練習問題3-6進変換1(base 1)入力基数b(2<=b<=10)と正整数n(10進)を入力し、nのb進表現を出力する.
分析:kを除いて余剰を取る
コード:
#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
	int b,n,x;
	int i=0;
	int buf[sizeof(int)*8];//     bit 
	scanf("%d%d",&b,&n);
	while(n!=0){
	   x=n%b;
	   buf[i++]=x;
	   n/=b;
	}
	while((--i)>=0){//    
		printf("%d",buf[i]);
	}
	printf("
"); return 0; }

練習問題3-7進変換2(base 2)入力基数b(2<=b<=10)と正整数n(b進)を入力し、nの10進表現を出力する.
分析:アルゴリズムは簡単で、バイナリが10進数に回転するアルゴリズムです.本題の核心はどのように正の整数nを解くかであり、本人が使用する方法は正の整数を文字列として処理し、scanf("%s")を用いてbuf文字配列に格納し、文字配列の大きさはsizeof(n)*8+1(b=2すなわちバイナリの場合、整数が4バイトの場合、bufは32+1すなわち"0")である.
コード:
#include "stdafx.h"
#include <string.h>
 

#define MAX sizeof(int)*8+1//     +1       '\0'

int getBase(int m,int b)
{//  m      ,b    
    int i,base=1;
	for(i=0;i<m;i++){
	    base*=b;
	}
	printf("base=%d
",base); return base; } int _tmain(int argc, _TCHAR* argv[]) { int b; int value=0,len,base; int i; char buf[MAX];// , scanf("%d%s",&b,buf); printf("buf=%s
",buf); len=strlen(buf); for(i=0;i<len;i++){ base=getBase(len-1-i,b); value+=(buf[i]-'0'+0)*base; } printf("%d
",value); return 0; } //2 11111111111111111111111111111110

練習問題3-8携帯電話のキーボード(keyboard)は、小文字からなる英語の単語を入力し、携帯電話のデフォルトの英語入力法のノックシーケンスを出力します.例えばpigという単語を打つには、1回p,3回i,(少しポーズを取った後)1回gを押してp 1 i 3 g 1と記入する必要がある(明らかに、本の中のこの部分の記述には明らかな誤りがあり、ここの記述に準じるべきである).
分析:本題アルゴリズムのフレームワークは簡単で、各文字が極めて対応する位置を出力します.本題の核心はどのように各アルファベットの必要なボタンの回数を探し当てることにあるので、本題の肝心な点はどのように携帯電話のキーボードを組織するかで、私のやり方は1つの配列で各アルファベットの必要なボタンの回数を記録することです:int key_times[26]={1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};key_timesは、aが0、bが1、cが2のように26文字の英字のシーケンス番号で、その値はボタンが必要な回数に対応しています.
コード#コード#
#include "stdafx.h"
#include "string.h"

#define MAX 1024+1//           1024
 
int key_times[26]={1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};//key_times   26        , a 0,b 1,c 2,           

int _tmain(int argc, _TCHAR* argv[])
{
	int i,pos;
	char buf[MAX];
	scanf("%s",buf);
	for(i=0;i<strlen(buf);i++){
	   pos=buf[i]-'a'+0;
	   printf("%c%d",buf[i],key_times[pos]);
	}
	printf("
"); return 0; }