Hatena::Groupcprogramming

てーげーC言語

2009-03-04

4-2

| 00:44

#include <stdio.h>
#include <ctype.h>

double atof (char s[]) {
  double val, power, sisu;
  int i, sign, sisuketa;

  for (i = 0; isspace(s[i]); i++)
    ;   

  sign = (s[i] == '-') ? -1 : 1;

  if (s[i] == '+' || s[i] == '-')
    i++;

  for (val = 0.0; isdigit(s[i]); i++)
    val = 10.0 * val + (s[i] - '0');

  if (s[i] == '.')
    i++;

  for(power = 1.0; isdigit(s[i]); i++) {
    val = 10.0 * val +(s[i] - '0');
    power *= 10.0;
  }

  sisu = 1.0;

  if(((s[i] == 'e') || (s[i] == 'E')) && (s[++i] == '-')){
    i++;
    for(sisuketa = 0; isdigit(s[i]); i++) {
      sisuketa = 10 * sisuketa + (s[i] - '0');
    }   

    for(sisu = 1.0; sisuketa > 0; sisuketa--) {
      sisu *= 10.0;
    }   
  }

  return sign * val / power / sisu;
}

int main() {
  char s[] = "10.5";
  char t[] = "3.42e-4";

  printf("%f\n", atof(s));
  printf("%f\n", atof(t));
  return 0;
}
# ./a.out                
10.500000
0.000342

[K&R}4-1

| 00:41

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

void reverse(char* s)
{
  int i, j;
  char temp, *p;

  i = j = 0;
  p = s;


  while(*p++) {
    i++;
  }

  --i;
  while(i > j) {
    temp = *(s+i);
    *(s+i) = *(s+j);
    *(s+j) = temp;
    i--;
    j++;
  }
}

int strrindex(char* s, char* t) {
  int len, i, j;

  len = strlen(s);
  i = len;

  reverse(t);

  while(i-- >= 0) {
    for(j = 0; (*(s+i) == *(t+j)) &&  (*(t+j) != '\0'); i--, j++) {
    }   

    if (*(t+j) == '\0')
      return i+1;
  }
  return -1; 
}

int main()
{
  char* s = "helloworld";
  char t[] = "world";
  char* u = "hogebarfuga";
  char v[] = "bar";
  char* w = "rubyperlphp";
  char x[] = "java";
  char* y = "helloworldhelloworld";
  char z[] = "hello";
  int rtn;

  rtn = strrindex(s, t);
  printf("%d\n", rtn);

  rtn = strrindex(u, v);
  printf("%d\n", rtn);

  rtn = strrindex(w, x);
  printf("%d\n", rtn);

  rtn = strrindex(y, z);
  printf("%d\n", rtn);

  return 0;
}
# ./a.out                
5
4
-1
10

2009-02-18

3-6

| 03:00

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

void reverse(char s[])
{
  int i, j;
  char temp, *p; 

  i = j = 0;
  p = s;
  

  while(*p++) {
    i++;
  }   
  --i;
  while(i > j) {
    temp = *(s+i);
    *(s+i) = *(s+j);
    *(s+j) = temp;
    i--;
    j++;
  }
}

void itoa(int n, char s[], int field_size)
{
  int i, sign, len;

  if ((sign = n) < 0)
    n = -n; 

  i = 0;
  do {
    s[i++] = n % 10 + '0';
  } while ((n /= 10) > 0); 

  if (sign < 0)
    s[i++] = '-';

  s[i] = '\0';
  
  len = strlen(s);
  while (len < field_size) {
    s[i++] = ' ';
    s[i] = '\0';
    len++;
  }

  reverse(s);
}

int main()
{
  char s[128];

  itoa(100, s, 5);
  printf("%s\n", s);
  itoa(100, s, 3);
  printf("%s\n", s);

  return 0;
}
# ./a.out                 
  100
100

2009-02-12

3-5

| 02:40

数値を文字に変える演算がいつもスッと出てこない!

#include <stdio.h>

void reverse(char *s) 
{
  int i, j;
  char temp, *p; 

  i = j = 0;
  p = s;
  

  while(*p++) {
    i++;
  }   

  while(--i > j) {
    temp = *(s+i);
    *(s+i) = *(s+j);
    *(s+j) = temp;
    i--;
    j++;
  }
}

void itob(int n, char* s, int b)  
{
  int d;
  char *p; 

  p = s;

  do {
   *p++ = (d = n % b) <= 9 ? d +'0' : d - 10 + 'a';
  } while((n/=b) != 0); 

  *p = '\0'; 

  reverse(s);
}

int main()
{
  char s[128];
  int n;

  n = 15;

  itob(n, s, 8);
  printf("%s\n", s);

  itob(n, s, 16);
  printf("%s\n", s);

  return 0;
}
# ./a.out                
17
f

2009-02-09

3-3

| 00:59

力技すぎる・・

アンサーブックの解答がすごいうまいと思った。ていうかこういうのどうやって書けるのか?

#include <stdio.h>
#define MAX_LENGTH 1024

void expand(char* s1, char* s2);

enum status{NONE, FROM_ARI, TO_ARI};

int main()
{
  char s2[MAX_LENGTH];

  expand("a-z", s2);
  printf("%s\n", s2);

  expand("a-b-c", s2);
  printf("%s\n", s2);

  expand("a-z0-9", s2);
  printf("%s\n", s2);

  expand("-a-z", s2);
  printf("%s\n", s2);

  expand("a-z-", s2);
  printf("%s\n", s2);

  return 0;
}

void expand(char* s1, char* s2) 
{
  char from, to, last;
  enum status sts;
  
  sts = NONE;
  from = to = '\0';
  
  while(*s1) {
    switch(*s1) {
      case '-':
        if (sts == NONE || sts == TO_ARI) {
          *s2++ = *s1;
          sts = NONE;
        }
        last = *s1;
        break;
      default:
        if (sts == NONE || sts == TO_ARI) {
          from = *s1;
          sts = FROM_ARI;
        } else if (sts == FROM_ARI) {
          to = *s1;
          while (from <= to) {
            *s2++ = from;
            from++;
          }
          sts = FROM_ARI;
          from = to+1;
        }
        last = *s1;
        break;
    }
    s1++;
  }

  if (last == '-')
    *s2++ = last;

  *s2 = '\0';
}
# ./a.out                
abcdefghijklmnopqrstuvwxyz
abc
abcdefghijklmnopqrstuvwxyz123456789
-abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz-

2009-02-08

3-2

| 15:56

タブと改行を¥t, ¥nで出力

#include <stdio.h>
#define MAX_LENGTH 256

void escape(char* s, char* t); 

int main()
{
  char s[256], t[256], c;
  char* tp; 
  char* sp; 
  
  sp = s;
  tp = t;

  while ((c = getchar()) != EOF) {
    *sp++ = c;
  }   
  *sp = '\0';

  escape(s, t); 
  printf("%s\n", t);    

  return 0;
}

void escape(char* s, char* t)
{
  while(*s) {
    switch(*s) {
      case '\n':
        *t++ = '\\';
        *t++ = 'n';
        break;
      case '\t':
        *t++ = '\\';
        *t++ = 't';
        break;
      default:
        *t++ = *s; 
    }   
    s++;
  }
  *t = '\0';
}
# ./a.out                
hello   world
!
hello\tworld\n!\n

逆版

#include <stdio.h>
#define MAX_LENGTH 256

void deescape(char* s, char* t);

int main()
{
  char s[] = "hell\to world\n!";
  char t[256];
//  char c;
  char* tp; 
  char* sp; 
  
  sp = s;
  tp = t;

//  while ((c = getchar()) != EOF) {
//    *sp++ = c;
//  } 
//  *sp = '\0';

  deescape(s, t); 
  printf("%s\n", t);    

  return 0;
}

void deescape(char* s, char* t)
{
  while(*s) {
    switch(*s) {
      case '\\':
        if (*(s+1) == 'n') {
          *t++ = '\n';
          s++;
        } else if (*(s+1) == 't') {
          *t++ = '\t';
          s++;
        } else {
          *t++ = '\\';
        }
        break;
      default:
        *t++ = *s; 
    }   
    s++;
  }
  *t = '\0';
}
# ./a.out                  
hell    o world
!

3-1

| 15:48

本にある二分検索

#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>

#define SIZE 1000000

double getrusage_sec()
{
    struct rusage t;
    struct timeval tv; 
    getrusage(RUSAGE_SELF, &t);
    tv = t.ru_utime;
    return tv.tv_sec + (double)tv.tv_usec*1e-6;
}

int binsearch(int x, int v[], int n); 

int main()
{
  int v[SIZE];
  int i;
  double t1, t2; 

  for(i=0;i<SIZE;i++)
    v[i] = i;

  t1 = getrusage_sec();
  printf("%d\n", binsearch(109, v, SIZE));
  t2 = getrusage_sec();
  printf("time = %10.70f\n", t2 - t1);

  return 0;
}

int binsearch(int x, int v[], int n)  
{
  int low, high, mid;

  low = 0;
  high = n-1;
  while (low <= high) {
    mid = (low+high) / 2;
    if (x < v[mid]) 
      high = mid -1; 
    else if (x > v[mid])
      low = mid + 1;
    else
      return mid;
  }
  return -1;
}
# ./a.out                
109
time = 0.0000280000000000002469136006766348145902156829833984375000000000000000

ループの中でチェックを1回しかしない版

#include <sys/resource.h>
#include <stdio.h>

#define SIZE 1000000

double getrusage_sec()
{
    struct rusage t;
    struct timeval tv; 
    getrusage(RUSAGE_SELF, &t);
    tv = t.ru_utime;
    return tv.tv_sec + (double)tv.tv_usec*1e-6;
}

int binsearch(int x, int v[], int n); 

int main()
{
  int v[SIZE];
  int i;
  double t1, t2; 

  for(i=0;i<SIZE;i++)
    v[i] = i;

  t1 = getrusage_sec();
  printf("%d\n", binsearch(109, v, SIZE));
  t2 = getrusage_sec();
  printf("time = %10.70f\n", t2 - t1);

  return 0;
}

int binsearch(int x, int v[], int n)  
{
  int low, high, mid;

  low = 0;
  high = n - 1;

  mid = (low+high) / 2;

  while (low <= high && v[mid] != x) {
    mid = (low+high) / 2;
    if (x < v[mid]) 
      high = mid - 1;
    else
      low = mid + 1;
  }

  if (v[mid] == x)
    return mid;

  return -1;
}
# ./a.out                
109
time = 0.0000259999999999999814592754887598857749253511428833007812500000000000

実行時間にはほとんど差はないのでは・・