1 给定一个长度为n的数组data,计算出data[i]-data[j]的最大值,0<=i<j<=n

 分析:

对于减法的计算,要是差值最大,必须要让被减数尽可能大,减数尽可能小,所以,把数组遍历一遍,存下当前最大值,并用最大值减去新进来的元素,保存当前最大的差值,更新当前最大值和当前最大的差值

def max_min(array):
    max_value = array[0]
    res = array[0]-array[1]
    for each in array[1:]:
        if each>max_value:
            max_value = each
        if res < max_value - each:
            res = max_value - each
    return res


def old_way(array):
    res = 0
    for i in range(len(array)-1):
        for j in range(i+1,len(array)):
            if array[i]-array[j]>res:
                res = array[i]-array[j]
    return res

if __name__ =='__main__':
    x = [int(i) for i in input().split()]
    print(max_min(x))
    print(old_way(x))

对比两种算法

发现第一种方法算法复杂为O(n)

第二种方法的时间复杂度为O(n^2)

2 字符串反转 'i am a student' 转化成 ' student a am i'

python实现:列表转化成字符串需要" ".join(list)

if __name__ == "__main__":
    s = input().split()
    def revstring(s):
        if not s:
            return 0
        else:
            res = ""
            s.reverse()
            res = " ".join(s)
        return res

如果后面有点号,可以使用正则化的形式,将其去掉

import re

def reve(arr):
    data = re.split(r"[ .,\n?]",arr)
    #data = arr.split(' ')
    data.reverse()
    res = " ".join(data)
    print(res)
    

reve("i am a student.")

结果如下

runfile('C:/Users/xu/Desktop/python/xiushiqi.py', wdir='C:/Users/leilxu/Desktop/python')

i am a student

s
Out[12]: ['i', 'am', 'a', 'student']

print(revstring(s))
student a am i

C语言实现

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

//反转一个单词[from,to]区间内的字母
void reserveString(char arr[], int from, int to)
{
	while (from < to)
	{
		char tmp = arr[from];
		arr[from] = arr[to];
		arr[to] = tmp;
		from++;
		to--;
	}
}

//反转一句话,以'\0'结尾
void reserve(char ch[], int len)
{
	int i = 0;
	int from = 0;
	int to = 0;
	while (i <= len)//数组中每个字符都要判定,包括'\0'
	{
		if (ch[to] == ' ' || ch[to] == '\0')
		{
			reserveString(ch, from, to - 1);   //先反转每个单词,[from,to-1]
			from = ++to;                    //寻找下一个单词。
		}
		else
		{
			to++;
		}
		i++;
	}
	reserveString(ch, 0, len - 1);  //再整体反转
}

int main()
{
	char ch[] = "i am a student.";
	printf("%s\n", ch);
	reserve(ch, strlen(ch));
	printf("%s\n", ch);
	return 0;
}

大华电话面试

 C语言里面的野指针,造成垃圾内存的原因

野指针不是NULL指针,是指向“垃圾”内存的指针。即它是随机指向的,系统自动对其初始化。

野指针会造成什么样的后果呢?

最大的问题:它会导致内存泄漏。

什么叫作内存泄漏?

指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

简单的说,内存泄漏分为两方面:1、非法访问空间 2、访问了已经释放的空间。

面试题:如何避免野指针?

1.首先我们要养成良好的编码习惯。

2.当我们定义一个指针的时候,直接让它指向NULL。因为NULL在宏定义是#define NULL (void *) 0  它代表的是零地址,而零地址是不能进行读写操作的。

3.要想给指针指向的空间赋初值的时候,必须给指针分配空间。

可是使用malloc()进行分配空间,它返回的是空间的首地址。

4.在分配空间后,我们首要做的是检查是否分配成功。

简单的检测方法:

if (p == NULL)     //p为指针变量
{
printf(“malloc分配失败!”);
eixt(1);      //结束整个程序,return 是结束一个函数
}

5.在使用malloc分配后的空间之前一定要对其清零。

因为我们分配的空间里面可能残留一些垃圾数据,这样会导致程序出错。

6.使用完空间后,记得释放空间,可以用free(p);//p为指针变量

7.释放完后可以让指针指向NULL,如:p = NULL

new和malloc

malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。

对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。 

既然new/delete的功能完全覆盖了malloc/free,为什么C++不把malloc/free淘汰出局呢?这是因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。
如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。 

2 存储过程和触发器

3 修饰器和类的区别