[语法]标准C函数time

  • 得到当前系统时间

使用time()函数获取当前时间

time_t now = time(NULL);
printf(“now: %d \n”, (int) now);

time_t类型:是一个整数,可以强转为int型来打印

(time_t的是一个整数,跟编译器有关,通常是32位整数或64位整数)

  • time_t

now的值表示自“1970-01-01 00:00:00”这个时间点的秒值数。

可以发现,每次运行,这个值都是变的。变化的值,就是中间相差的时间(秒数)

但是,我们如何使用它?

 

  • tm: 转化成“年月里时分秒”

可以把time_t转成年月日时分秒
使用localtime()函数
tm * localtime(const time_t *p);

输入参数:time_t*
返回值 : tm*
其中,tm是一个struct类型,包含了年、月、日、时、分、秒、星期等详细信息。

struct tm的定义
struct tm
{
int tm_sec; // 秒: 0~59
int tm_min; // 分:0~59
int tm_hour; // 时: 0~23
int tm_mday; // 日:1~31
int tm_mon; // 月:0~11
int tm_year; // 年: +1900
int tm_wday; // 星期几: 0~6,其中0表示星期日
int tm_yday; // 这一年的第几天: 0~365
};

time_t now = time(NULL);
tm info = *localtime(&now); // 保存结果

int year = info.tm_year + 1900;
int month = info.tm_mon + 1;
int day = info.tm_mday;
int hour = info.tm_hour;
int minute = info.tm_min;
int second = info.tm_sec;

例:求出自今天起、300天以后的日期值。

time_t now = time(NULL); // 当前时间
now += 300 * 24 * 3600; // 加上时间间隔
tm info = *localtime(&now);

  • “年月里时分秒”转换为time_t?time_t的优势:一个整数,容易存储和计算我们可以把一个时间转成time_t, 比如,”2015-02-01 00:00:00″ 转成 time_t使用mktime函数
    time_t mktime(tm * p);

time_t convert(int year, int month, int day,
int hour, int minute, int second)
{
tm info = {0};
info.tm_year = year – 1900;
info.tm_mon = month – 1;
info.tm_mday = day;
info.tm_hour = hour;
info.tm_min = minute;
info.tm_sec = second;
return mktime(&info);
}
注:tm_wday和tm_yday不需要填写

 

例:计算两个日期之间隔了多少天
比如,“2015-4-6”到“2013-2-2”

time_t start = convert(2013,2,2,0,0,0) ;
time_t end = convert(2015,4,6,0,0,0);
// 差值
int diff = (int)(end – start);
// 计算是多少天
int days = diff / (24*3600);

[语法]标准C函数- stdio.h和stdlib.h

实际工程中常用的一对函数:

sprintf – 格式化字符串, 首字母s表示string
sscanf – 解析字符串

例:
char buf[128];
sprintf(buf, “Name:%s , Age:%d”, “shaofa”, 33);


char* buf = (char*)malloc(128); // 参考12章malloc用法
sprintf(buf, “Name:%s , Age:%d”, “shaofa”, 33);

sscanf用于提取字符串的字段
const char* text = “2015-12-13”;
int year,month,day;
int n = sscanf(text, “%d-%d-%d”,
&year, &month, &day);
if( n != 3)
{
printf(“bad format!\n”);
}
sscanf的返回值表示实际解析出的字段的个数

 

 

rand与srand : 随机数的生成

要确保每次程序启动时,传入不同的seed。通常是传入当前的时间。
注: time函数返回一个整数
srand(time(NULL));
for(int i=0; i<10; i++)
{
printf(“%d \n”, rand());
}
srand: 只需要main()启动时运行一次就够了。不需要每次rand()之前都调用srand。

对rand()结果取模

通常地,要对rand()返回的结果取模,使其坐落在一个区间内。
比如,要在100和160之间随机取一个数。
int r = rand() % 60 + 100;
其中,60是区间长度

对rand()结果取模

比如,要在0.00和1.00之间取一个小数
int r = rand() % 100;
double rp = r / 100.0; // 转成小数

或者,使用 RAND_MAX
double rp = (double)rand()/ RAND_MAX ;
RAND_MAX是一个整型数字,表示rand()函数产生的随机数的区间上限。(下限是0)

[语法]字符串的分割

#include<stdio.h>

int split(char text[], char* parts[])
{	
    int count = 0; // 分段的个数
    int start = 0; // 每一分段的首地址
    int flag = 0; // 遍历text,标识当前是否处于有效字符

    int stop = 0; // 是否到达结束
    for(int i=0; !stop ; i++)
    {
        char ch = text[i];
        if(ch == 0) 
            stop = 1; // 结束循环

        if(ch == ',' || ch == '\0' || ch == ' ' || ch == '\t' )
        {
            if(flag) // 遇到分隔符,且当前状态为flag=1
            {
                flag = 0;

                text[i] = 0; // 修改为结束符,完成分段
                parts[count] = text + start; // 记录首地址
                count ++;				
            }
        }
        else
        {
            if(!flag) // 遇到有效字符,且当前状态为flag=0
            {
                flag = 1;
                start = i;
            }
        }
    }
    return count; // 返回分段个数
}

int main()
{
    char text[] = "hello,world,,good,\tmorning ";
    
    char* parts[16];
    int count = split(text, parts);


    return 0;
}

 

[语法]字符串的插入与删除

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

void erase(char text[], int index)
{
    int len = strlen(text);
    for(int i = index; i<len ; i++)
    {
        text[i] = text[i + 1]; // 后面的字符前移
    }
}


int main()
{
    char str[10] = "hello";
    erase(str, 1);
    
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void erase(char text[], char del)
{
    int len = strlen(text); // 原字符串长度

    int count = 0;
    char* copy = (char*) malloc(len + 1);
    for(int i=0; i<len; i++)
    {
        char ch = text[i];
        if(ch != del )
        {
            copy[count] = ch;
            count ++;
        }
    }
    copy[count] = 0; // 添加结束符
    
    strcpy(text, copy); // 拷回原字符串
    free(copy); // 释放内存
}

int main()
{
    char str[] = "China is a great country with a long history";
    erase(str, 'a');
    
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void insert(char text[], int index, char ins)
{
    int len = strlen(text);
    for(int i = len; i >index ; i--)
    {
        text[i] = text[i - 1]; // 后面的字符前移
    }
    text[index] = ins;
}


int main()
{
    char str[10] = "hello";
    insert(str, 1, 'X');
    
    return 0;
}

 

[语法]删除与插入链表节点

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

struct Student
{
    int id;
    char name[16];
    Student* next;
};

// 定义了一个有头节点
Student m_head = {0};

// 按顺序插入节点
int insert(Student* obj)
{
    Student* cur = m_head.next; // 当前节点current
    Student* pre = &m_head;  // 上一个节点previous
    while(cur)
    {		
        if(obj->id < cur->id) // 找到这个位置
            break;

        pre = cur;
        cur = cur->next;  // 找到最后一个对象
    }

    // 插入到pre节点的后面
    obj->next = pre->next;
    pre->next = obj;
    return 0;
}

// 按id查找并删除节点
void remove(int id)
{
    Student* cur = m_head.next; // 当前节点current
    Student* pre = &m_head;  // 上一个节点previous
    while(cur)
    {		
        if(id == cur->id) // 找到这个位置
        {
            // 删除该节点
            pre->next = cur->next;
            free(cur);
            break;
        }
        pre = cur;
        cur = cur->next;  // 找到最后一个对象
    }
}

// 遍历
void show_all()
{
    Student* p = m_head.next; 
    while(p)
    {
        printf("ID: %d, name: %s\n", p->id, p->name);
        p = p->next; // 下一个对象
    }
}

int main()
{
    Student* obj = NULL;
    

    obj = (Student*)malloc (sizeof(Student));
    obj->id = 8;
    strcpy(obj->name, "888");
    insert(obj);

    obj = (Student*)malloc (sizeof(Student));
    obj->id = 1;
    strcpy(obj->name, "111");
    insert(obj);

    obj = (Student*)malloc (sizeof(Student));
    obj->id = 4;
    strcpy(obj->name, "444");
    insert(obj);

    obj = (Student*)malloc (sizeof(Student));
    obj->id = 3;
    strcpy(obj->name, "333");
    insert(obj);

    obj = (Student*)malloc (sizeof(Student));
    obj->id = 5;
    strcpy(obj->name, "555");
    insert(obj);

    remove(3);
    remove(2);
    show_all();
    return 0;
}

 

[语法]有头链表的构造

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

struct Student
{
    int id;
    char name[16];
    Student* next;
};

// 定义了一个有头节点
Student m_head = {0};

// 插入一个对象到链表中
// void add(Student* obj)
// {
// 	obj->next = m_head.next;
// 	m_head.next = obj;
// }

void add(Student* obj)
{
    Student* p = &m_head;
    while(p->next)
        p = p->next;  // 找到最后一个对象
    p->next = obj;   //  把obj挂在最后一个对象后面
    obj->next = NULL;  // 现在obj作为最后一个对象
}


int main()
{
    Student* obj_1 = (Student*)malloc (sizeof(Student));
    obj_1->id = 1;
    strcpy(obj_1->name, "X");
    add(obj_1);

    Student* obj_2 = (Student*)malloc (sizeof(Student));
    obj_2->id = 2;
    strcpy(obj_2->name, "Y");
    add(obj_2);
    return 0;
}

 

[语法]malloc示例

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


struct Car
{
    char maker[32]; // 制造商
    int  price;  // 价格
};
struct Citizen
{
    char name[32]; // 名字
    int  deposite; // 存款
    Car* car;  // NULL时表示没车
};

void buy(Citizen* owner)
{ 
    // 创建一个对象
    Car* car = (Car*) malloc(sizeof(Car));
    strcpy(car->maker, "Chevrolet");
    car->price = 10;

    // 保存此对象 (确切地说是记住了指针)
    owner->car = car; // 有车了
    owner->deposite -= car->price; // 钱没了
}

void discard(Citizen* owner)
{
    free(owner->car);  // 此对象被销毁
    owner->car = NULL;  // 回到无车状态   
}

//也有可能会买给别人,
void sell(Citizen* owner, Citizen* other)
{
    Car* car = owner->car;

    car->price *= 0.5; //半价出售
    other->deposite -= car->price;
    other->car = car; // 别人拥有了这辆车

    owner->deposite += car->price; // 收回一部分成本
    //free(car); // oh,no! 不能free,这车在别人手里
    owner->car = NULL;  // 回到无车状态   
}



int main()
{
    while(1)
    {
        void* ptr = malloc(1024*512);
        if(!ptr)
        {
            printf("no memory!\n");
        }
    }

    //discard(&shaofa);
    return 0;
}

 

[演算法笔记]輾轉相除法

int gcd1(int a, int b)
{
    // 令 a 比 b 大,比較容易思考。
    while (b != 0)
    {
        int t = a % b;
        a = b;
        b = t;
    }
    return a;
}

int gcd2(int a, int b)
{
    // 令 a 比 b 大,比較容易思考。
    if (b == 0)
        return a;
    else
        return gcd(b, a % b);
}

 

UVa 10922 2 the 9s

我們知道要怎麼確定一個整數是不是 9 的倍數-如果它每位數的總和是9的倍數,那它就是9的倍數。這種檢驗的方法其實是一種遞迴的方法,而且我們把這種方法遞迴的深度稱作 N 的 9-degree 。

你的工作就是,給你一個正整數N,判斷他是不是9的倍數,而且如果他是9的倍數你還需要判斷它的 9-degree。

Input 

輸入含有多組測試資料。每組測試資料一列包含一個正數 N。

當 N=0 時代表輸入結束;輸入的數最大可以到1000位數。

Output 

對於每一組測試資料,請輸出它是否是 9 的倍數及它的 9-degree。輸出格式請參考Sample Output。

Sample Input 

999999999999999999999
9
9999999999999999999999999999998
837
0

Sample Output 

999999999999999999999 is a multiple of 9 and has 9-degree 3.
9 is a multiple of 9 and has 9-degree 1.
9999999999999999999999999999998 is not a multiple of 9.
837 is a multiple of 9 and has 9-degree 2.

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string s;
    while(cin >> s){
        if (s.length() == 0 || s[0] == '0'){
            break; 
        }

        int sum = 0;
        for (int i = 0; i < s.length(); i++){
            sum += s[i] - '0'; //先把所有位加起来
        }

        int dep = 0;
        int is9mul = 0;

        if (sum % 9 == 0){
            is9mul = 1; //如果一个数是9的倍数,肯定能一直递归下去
            dep = 1; //开始的时候,只要能被9整除,深度就是1;
        }

        while (sum % 9 == 0 && sum > 9){
            int temp = sum;
            sum = 0;
            while(temp){
                sum += temp % 10; 
                temp /= 10;
            }
            dep++;
        }
        cout << s << " is ";
        if (!is9mul) cout << "not ";
        cout << "a multiple of 9";
        if (dep) cout << " and has 9-degree " << dep;
        cout << "." << endl;
    }
    return 0;
}

 

UVa 10212 The Last Non-zero Digit.

在這個問題中,給你2個整數N,M。請你找出NPM(在N個東西種找出M個東西排列不同的方式)最後一個不為0的數字。例如:10P3=10*9*8=720,所以答案為2。

Input

每筆測試資料一列。每列有2個整數 N(0 <= N <= 20000000),M(0 <= M <= N)。

Output

對每一列輸入,請輸出NPM最後一個不為0的數字。

Sample Input

10 10
10 5
25 6

Sample Output

8
4
2

#include <iostream>
using namespace std;

long long P(long long n, long long m)
{
    long long ans=1;
    for (long long i = n - m + 1; i<=n; i++){
        ans *= i; 
    }
    
    return ans;
}

long long calc(long long p)
{
    if (p % 10 == 0)
        return calc(p / 10);
    else
        return p % 10;
}

int main()
{
    long long n, m, p;
        while(cin >> n >> m){
        if (n < m) continue;
        p = P(n, m);
        //cout << p << endl;
        cout << calc(p) << endl;
    }
}