1. 程式人生 > >演算法之美[從菜鳥到高手演練]之一些個小演算法

演算法之美[從菜鳥到高手演練]之一些個小演算法

1、10000以內的完數
/*
* 問題描述:求10000以內的完數。
* 完數即:一個數等於它的不同因子的和
* 如6=1+2+3.8!=1+2+4
* xtfggef 2012/5/16
*/
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

/*
* 思路:先把10000以內的完數算出來,放在
* 一個vector裡,再和給定的數比較,如果小於
* 給定的數,就打印出來。還有一個思路:就是
* 直接計算小於給定的數的完數,這樣可以
* 少計算點兒。
*/
int main(int argc, char * argv[])
{
	//此處引入檔案操作
	ifstream cin("seed.txt");
	int n;
	vector<int> a;
	/*
	* 此處需要說明一下,為什麼下面的for
	* 迴圈為i=i+2,這說明完數只有在偶數裡
	* 有,奇數在一個小的範圍內沒有完數
	* 具體在哪個範圍,數學界還沒有證明出來
	*/
	for(int i=2; i<10000; i=i+2)
	{
		int sum = 1;
		for(int j=2; j<=i/2; j++)
		{
			//如果模除為0,則是它的因子,所以加上去
			if(i%j==0) sum=sum+j;
		}
		if(sum==i) a.push_back(i);
	}
	while(cin>>n)
	{
		cout << n << ":";
		for(int k=0; k<a.size(); k++)
		{
			if(a[k]<=n)
				cout << " " << a[k];
		}
		 cout << endl;
	}
	return 0;
}

2、求三位數對稱素數

/*
* 問題描述:找出3位數對稱素數
* 如101就是,787也是,896不是
* 是的話輸入YES,否則輸出NO
* xtfggef 2012/5/16
*/
#include<iostream>
#include<cmath>
using namespace std;

bool isPrime(int);
int main(int argc, char * argv[])
{
	int n;
	cin >> n;
	//核心
	cout << (n>100&&n<1000&&n/100==n%10&&isPrime(n)?"YES\n":"NO\n");
	return 0;
}
/*
* 判斷是否是素數
*/
bool isPrime(int n)
{
	int sqr = sqrt(n*1.0);
	for(int i=2; i<=sqr; i++)
	{
		if(n%i==0)
			return false;
	}
	return true;
}

3、求兩個數的最大公約數

/*
* 求兩個數的最大公約數
* xtfggef 2012/5/16
*/
#include<stdio.h>

int gcd(int,int);
void main()
{
	int a = 5;
	int b = 8;
	int c = gcd(a,b);
	printf("%d\n",c);
}
int gcd(int a, int b)
{
	while(a!=b)
	{
		if(a>b)
			a=a-b;
		else
			b=b-a;
	}
	return a;
}

最小公倍數類似,藉助於最小公倍數=X*Y/gcd(X,Y);就OK了。

此處注意:為了使計算不超出範圍,最好寫成:X/gcd(X,Y)*Y

4、取代求模運演算法

 k = (j + rotdist)%n
可以寫為:
k = j + rotdist;
if(k>n)
k -= n;

5、求相鄰子向量的最大和(出自程式設計珠璣)

/*
* 找出任何相鄰子向量的最大和
* xtfggef 2012/5/7
*/
#include<stdio.h>

int max(int a,int b)
{
	return (a>b)?a:b;
}
void main()
{

	int a[10] = {31,-41,59,26,-53,58,97,-93,-23,84};
	int maxsofar = 0;
	int maxendinghere = 0;
	for(int i=0; i<10; i++)
	{
		//遇到負數,直接賦0,相當於跳過
		//遇到大一點的數,從該數開始
		maxendinghere=max(maxendinghere+a[i],0);
		maxsofar=max(maxsofar,maxendinghere);
	}
	printf("%d\n",maxsofar);
}

6、 給定一個整型陣列a,元素個數為n,求在a中出現n/2次以上的元素,並打印出來。

package com.xtfggef.hashmap;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 列印在陣列中出現n/2以上的元素
 * 利用一個HashMap來存放陣列元素及出現的次數
 * @author erqing
 *
 */
public class HashMapTest {
	
	public static void main(String[] args) {
		
		int [] a = {2,3,2,2,1,4,2,2,2,7,9,6,2,2,3,1,0};
		
		Map<Integer, Integer> map = new HashMap<Integer,Integer>();
		for(int i=0; i<a.length; i++){
			if(map.containsKey(a[i])){
				int tmp = map.get(a[i]);
				tmp+=1;
				map.put(a[i], tmp);
			}else{
				map.put(a[i], 1);
			}
		}
		Set<Integer> set = map.keySet();
		for (Integer s : set) {
			if(map.get(s)>=a.length/2){
				System.out.println(s);
			}
		}
	}
}
7、HDOJ Problem 1000 Java實現
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNextInt()){    
            int a = in.nextInt();
            int b = in.nextInt();
            int c = sum(a,b);
            System.out.println(c);
        }
    }
    public static int sum(int a,int b){
        return a+b;
    }
}

8、HDOJ Problem 1001 C++實現

#include <iostream>
using namespace std;
int main()
{
    unsigned int num; 
    while (cin >> num)
    {
        cout << (1+num)*num/2 << endl << endl ; 
    }

    return 0;
}

9、HDOJ Problem 1002 Java實現
import java.math.BigInteger;
import java.util.Scanner;

public class Main
{
    public static void main(String[] args) 
    {
        Scanner scanf = new Scanner(System.in);
        while(scanf.hasNext())
        {
            int n;
            int i=1,x=0;
            n=scanf.nextInt();
            while(n--!=0)
           {
               if(x++!=0)
                   System.out.println();
               BigInteger a,b,sum;
               a=scanf.nextBigInteger();
               b=scanf.nextBigInteger();
               sum=a.add(b);
               System.out.println("Case"+" "+ i++ +":");
               System.out.print(a+" "+"+"+" "+b+" "+"="+" ");
               System.out.println(sum);
           }
        }
    }
}

10、Java實現矩陣的轉置
package com.xtfggef.algo;

/**
 * 矩陣的轉置
 * 
 * @author erqing
 * 
 */
public class Matrix {

	public static void main(String[] args) {
		int array[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
		int array2[][] = new int[3][3];
		System.out.println("轉置前:");
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j] + " ");
				array2[j][i] = array[i][j];
			}
			System.out.println();
		}
		System.out.println("轉置後:");
		for (int k = 0; k < array2.length; k++) {
			for (int h = 0; h < array2[k].length; h++) {
				System.out.print(array2[k][h] + " ");
			}
			System.out.println();
		}
	}

}

11、Java實現計算時間差
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Tiemp {
    public static void main(String args[]){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String s1 = "20080808";
        String s2 = "20080908";
        try {
            Date d1 = sdf.parse(s1);
            Date d2 = sdf.parse(s2);
            System.out.println((d2.getTime() -  d1.getTime())/(3600L*1000)); 
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

12、判斷ip合法性

1、從.的數量來看,不能大於3個

2、每兩個點兒之間的數必須在0~255之間

3、每個除.之外的數必須<9且>0

4、第一個、最後一個字元不能是.

#include <stdio.h>

int is_valid_ip(const char *ip)

{
	
    int section = 0; //每一節的十進位制值
    int dot = 0; //幾個點分隔符
    int last = -1; //每一節中上一個字元

	if(*ip!='.')
	{
		while(*ip)		
		{		
			if(*ip == '.')				
			{				
				dot++;	
				if(dot > 3)					
				{					
					return 0;					
				}				
				if(section >= 0 && section <=255)					
				{					
					section = 0;
				}else{					
					return 0;				
				}
				
			}else if(*ip >= '0' && *ip <= '9')
			{				
				section = section * 10 + *ip - '0';			
				if(last == '0')					
				{					
					return 0;				
				}				
			}else{			
				return 0;				
			}			
			last = *ip;
			ip++;			
		}		
		if(section >= 0 && section <=255)		
		{			
			if(3 == dot)				
			{				
				section = 0;				
				printf("IP address success!\n");
				return 0;				
			}			
		}		
		return 1;
	}
	else
	{
		printf("格式錯誤!");
		return 0;
	}
}
int main()
{	
    is_valid_ip("23.249.22.123");
	return 0;	
}

13、判斷字串是否是迴文

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

/*判斷使用者輸入的字串是否為迴文
 *迴文是指順讀和反讀都一樣的串
 *例:abccba為迴文,abcdab不是迴文
*/

int Palindrome(const char *str)
{
	int length = strlen(str);
	for(int i = 0; i <= length/2; i++)
	{
		if(str[i] != str[length-i-1])
		{
			return -1;
		}
	}
	return 1;
}

int main()
{
	char s[100];
	gets(s);
	int result = Palindrome(s);
	if(result == 1)
	{
		printf("字串是迴文");
	}
	else
	{
		printf("字串不是迴文");
	}
}


 

14、字串轉換為整數
#include<iostream>
#include<string>
#include<assert.h>

using namespace std;

int str_2_int(string str)
{
	assert(str.size()>0);
	int pos = 0;
	int sym = 1;

	if(str[pos] == '+')
		pos++;
	else if(str[pos] == '-')
	{
		pos++;
		sym=-1;
	}
	int num =0;
	while(pos<str.length())
	{
		assert(str[pos]>='0');
		assert(str[pos]<='9');
		num = num*10+(str[pos]-'0');
		assert(num>=0);
		pos++;
	}
	num*=sym;
	return num;
}
int main()
{
	string str = "-1024";
	int num = str_2_int(str);
	cout << num << endl;
	return 0;
}