Pages

2010年10月2日 星期六

Java String 依照單字出現次數/頻率高的依序印出

功能:
依照每個單字出現的次數,由大到小,排列印出。

假設:
String oriString = "This is a book. That is a pencil"

輸出:
is 出現 2 次
a 出現 2 次
This 出現 1 次
That 出現 1 次
book 出現 1 次
pencil 出現 1 次

程式碼:
import java.util.regex.*;
import java.util.*;

public class StringSort {
 public static void main(String[] args){
  String oriString = "This is a book. That is a pencil.";
  Pattern p = Pattern.compile("\\w[^\\.\\s]*");
  Matcher m = p.matcher(oriString);
  
  Set<string> sortVerb = new TreeSet<string>();
  ArrayList<string> strArray = new ArrayList<string>();
  while(m.find()){
   strArray.add(m.group());
   sortVerb.add(m.group());
  }

  //計算oriString中的各個單字的次數
  int[] verbCount = new int[sortVerb.size()];
  int index = 0;
  for(String s : sortVerb){
   int count = 0;
   for(String sr : strArray){
    if(s.equals(sr))
     count++;
   }
   verbCount[index++] = count;
  }

  //開始排序
  int[] indexArray = new int[sortVerb.size()];
  for(int i = 0; i < indexArray.length; i++)
   indexArray[i] = i;
  int temp, indexTemp;
  index = 0;
  for (int f = 1; f < sortVerb.size(); f++) {
      if (verbCount[f] < verbCount[f-1])
       continue;
      temp = verbCount[f];
      indexTemp = indexArray[f];
      index = f-1;
      while ((index >= 0)&&(verbCount[index] < temp)) {
       verbCount[index+1] = verbCount[index];
       indexArray[index+1] = indexArray[index];
       index--;
      }
      verbCount[index+1]=temp;
      indexArray[index+1] = indexTemp;
  }
  Object[] printStr = sortVerb.toArray();
  for(int i = 0; i < indexArray.length; i++)
   System.out.println(printStr[indexArray[i]].toString()+"出現 "+verbCount[i]+"次");
 }
}

執行結果:
a出現 2次
is出現 2次
That出現 1次
This出現 1次
book出現 1次
pencil出現 1次

Linking-List Implement

[轉載] from: http://www.cnblogs.com/oomusou/archive/2008/03/22/1117686.html
Abstraction
使用C語言簡單的實現linked list,並用C++的std::vector實作出相同的功能作比較。
Introduction
學習資料結構,第一個要學的就是linked list,本文示範最簡單的linked list實現,包含建立與顯示,可把它當成linked list的標準範本,畢竟步驟都差不多。
一個基本的問題:為什麼需要linked list?若要將大量資料存到記憶體,你會想到什麼?第一個想到的就是array,但C語言是個靜態語言,array必須事先宣告大小,這樣compiler才能進行最佳化,若到時候沒用這麼多記憶體,就白白浪費記憶體了。或許你會說array可以配合malloc()變成動態array,但前提是你必須告訴malloc()要建立多大的array,若連要建立多大的陣列也不確定,而是在run-time看有多少資料就建立多大,這時連malloc()的動態array也不能用了,此時就得靠linked list。
linked list是資料結構的基礎,基本上就是靠struct如火車車廂那樣連在一起,run-time有需要時,在動態掛一個struct上去。

For C語言:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLEN 255

struct list {
  int  no;
  char name[SLEN];
  struct list *next;
};
int main() {
  int no;
  char s[255];
  struct list *head    = NULL;
  struct list *current = NULL;
  struct list *prev    = NULL;

  while(1) {
    printf("No. = ");
    scanf("%d", &no);
    if (no == 0)
      break;

    printf("Name = ");
    scanf("%s", s);

    current = (struct list *)malloc(sizeof(struct list));
    if (current == NULL)
      exit(EXIT_FAILURE);

    current->next = NULL;

    current->no = no;
    strncpy(current->name, s, SLEN -1);
    current->name[SLEN -1] = '\0';

    if (head == NULL)
      head = current;
    else
      prev->next = current;

    prev = current;
  }

  // display linked list
  current = head;
  while(current != NULL) {
    printf("No. = %d, Name = %s\n", current->no, current->name);
    current = current->next;
  }

  // free linked list
  current = head;
  while(current != NULL) {
    prev = current;
    current = current->next;
    free(prev);
  }
  return 0;
}
執行結果:
1
ssss
2
kkkk
3
gggg
4
llll
0
No. = Name = No. = Name = No. = Name = No. = Name = No. = No. = 1, Name = ssss
No. = 2, Name = kkkk
No. = 3, Name = gggg
No. = 4, Name = llll
好吧,我承認怪怪的,可以Work了!

For C++:
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class List {
public:
  int no;
  string name;
};

int main() {
  vector<list> vec;

  while(1) {
    List list;
    cout << "No. = ";
    cin >> list.no;

    if (list.no == 0)
      break;

    cout << "Name = ";
    cin >> list.name;

    vec.push_back(list);
  }

  vector<list>::iterator iter = vec.begin();
  for(; iter != vec.end(); ++iter)
    cout << "No. = " << iter->no << ", Name = " << iter->name << endl;
  return 0;
}

C++看起來簡單多了!

C語言指標範例(指標++)

C語言中最令初學者人頭大的指標,其實很容易記錯
指標的運算元順序是由右到左(書上寫的),實際來測試一下

#include<stdio.h>
int data[2] = {100,200};
int moredata[2] = {300,400};
int main(void){
 int * p1, * p2, * p3;
 p1 = p2 = data;
 p3 = moredata;
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1, *p2, *p3);
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1++, *++p2, (*p3)++);
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1, *p2, *p3);
 //括號測試
 printf("It is equal result...\n");
 p1 = p2 = data;
 p3 = moredata;
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
    *(p1++), *(++p2), (*p3)++);
 printf(" *p1 = %d, *p2 = %d, *p3= %d\n",
   *p1, *p2, *p3);
  return 0;
}

*p1 = 100, *p2 = 100, *p3= 300
 *p1 = 100, *p2 = 200, *p3= 300
 *p1 = 200, *p2 = 200, *p3= 301
It is equal result...
 *p1 = 100, *p2 = 200, *p3= 301
 *p1 = 200, *p2 = 200, *p3= 302

由此得知,*p1++ 相等於 *(p1++)
而不是(*p)++,我之前記錯了><

C/C++[微小位元][數字&數字]

最近,因為面試的關係,想把一些東西弄清楚,所以做了一些測試:
以下是微小位元的測試,實際是就是二進位運算啦,考是算錯(怪怪)

#include<stdio.h>

int main(void){
  int a = 44;
  int b = 55;
  int c = 33;
  int d = -20;
  printf("uni-micro operator: \n");
  printf("a & b = %d\n", a & b);
  printf("b & c = %d\n", b & c);
  printf("c & d = %d\n", c & d);
  printf("b & b = %d\n", b & b);
  printf("a | b = %d\n", a | b);

  printf("double-micro operator: \n");
  printf("a && b = %d\n", a && b);
  printf("a || b = %d\n", a || b);

  printf("while-micro operator: \n");
  while( a & b){
   printf("a ^ b = %d, ", a ^ b);
   a--;
   if(a < 40){
    break;
   }
  }
  printf("\n");
  while( a ^ d){
     printf("a ^ d = %d, ", a ^ d);
     a--;
     if( a ^ d < 0){
      break;
     }
  }

  return 0;
}
結果:
uni-micro operator: 
a & b = 36
b & c = 33
c & d = 32
b & b = 55
a | b = 63
double-micro operator: 
a && b = 1
a || b = 1
while-micro operator: 
a ^ b = 27, a ^ b = 28, a ^ b = 29, a ^ b = 30, a ^ b = 31, 
a ^ d = -53, 

由結果知道,while迴圈對負號的數值也會進入迴圈跑,我之前已為負的就不會跑= ="
學習中...