Home Authors Posts by 可乐

可乐

419 POSTS 5 COMMENTS

0 92
/**
 * 这是一份文档注释;第二章作业(编程题)
 *work 1.0;
 * 以如下结尾:位运算;
1.实现奇数相加;
class Scratch{
    public static void main(String[]args) {
        System.out.println("实现100以内奇数相加");
        int sum = 0, i = 0;
        for (i = 0; i < 100; i++) {
            if (i % 2 != 0) {
                sum += i;
            }
        }
        System.out.println("和为" + sum);
    }
}
2.冒泡排序;
class Scratch {
    public static void main(String[] args) {
        int i = 0, j = 0;
        int arr[] = new int[]{25, 24, 12, 76, 101, 96, 28};
        for (i = 0; i < arr.length - 1; i++) {
            for (j = 0; j < arr.length - 1 - i; j++) {
                int temp;
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }//冒泡排序;
        for (i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("The Length of the array is "+arr.length);
    }
}*/
注意:与C不同,java不可i&1判断奇数偶数;
java中的if()条件为true和false,只能为布尔类型;
C语言中的if()条件为非0和0,甚至可以为字符;

[et_pb_section admin_label=”section”]
[et_pb_row admin_label=”row”]
[et_pb_column type=”4_4″]
[et_pb_text admin_label=”Text”]
给定一个链表,判断链表中是否有环。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

bool hasCycle(struct ListNode *head) {
    struct ListNode *arr[10000];//指针数组;
    struct ListNode *P=NULL;
    for(int i=0;i<10000;i++){
        arr[i]=NULL;
    }//指针数组初始化;
    int i=0;
    while(head!=NULL){
        arr[i]=head;
        head=head->next;
        i++;
    }//这一步错误,因为如果该链表为环状链表的话会无线循环下去;报错为索引超出范围;
    P=arr[i-1];
    for(i=0;i<10000;i++){
        if(arr[i]==NULL)break;
        if(arr[i]==P->next){
            return true;
        }
    }
    return false;
}

[/et_pb_text]
[/et_pb_column]
[/et_pb_row]
[/et_pb_section]

数据的表示:

 

R进制转十进制:用按权展开法(10100)2=1*2的4次方+1*2的二次方;(10100.01)=1*2的4次方+1*2+1*2的负二次方;

十进制转R进制:用短除法;

二进制转8和16:三位二进制换一位八进制,四位二进制换一位十六进制;

正数:原码补码反码相同,最高位为0表示正;

负数:反码=原码除开符号位取反,补码=反码+1;例如-1原码:1000 0001,反码:1111 1110,补码:1111 1111,移码:“1”表示正数,“0”表示负数,数值部分与补码相同。

使用补码来进行加减法运算;

1.C 库函数 – isalpha()

C 标准库 - <ctype.h> C 标准库 – <ctype.h>

描述

C 库函数 void isalpha(int c) 检查所传的字符是否是字母。


2.判断字符是否为数字的函数–int isdigit( int ch )

用于判断字符是否为字母的函数–int isdigit( int ch )。

【包含的头文件】需要引入的头文件:#include <ctype.h>

【功能】如果参数是0到9之间的数字字符,函数返回非零值,否则返回零值;

  1. char c;
  2.  
    scanf( “%c”, &c );
  3.  
    if( isdigit(c) )
  4.  
    printf( “You entered the digit %c\n”, c );
其他详情见:
https://www.runoob.com/cprogramming/c-standard-library-ctype-h.html;

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head){   
    //反转链表 即使用头插法;
     struct ListNode * Ahead=(struct ListNode*)malloc(sizeof(struct ListNode));//头节点;
     Ahead->next=NULL;
     struct ListNode *p=head,*q=p;//初始化;
     while(q!=NULL){//q为当前插入的点;
         p=q->next;
         q->next=Ahead->next;
         Ahead->next=q;
         q=p;
     }//头插法反转成功;
     return Ahead->next;
}
/*递归如下;
#include <stdio.h>
#include <stdlib.h>
void  reveral(struct ListNode* p, struct ListNode* q, struct ListNode* Ahead);
int main() {
    struct ListNode* l1 = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode* head = l1;
    for (int i = 0; i < 5; i++) {
        int a;
        struct ListNode* P = (struct ListNode*)malloc(sizeof(struct ListNode));
        scanf_s(“%d”, &a);
        P->val = a;
        P->next = NULL;
        l1->next = P;
        l1 = P;
    }//创建完毕;
    struct ListNode* Ahead = (struct ListNode*)malloc(sizeof(struct ListNode));
    Ahead->next = NULL;
    struct ListNode* p = head, * q = p;//初始化;
    reveral(p, q, Ahead);
    Ahead = Ahead->next;
    for (int i = 0; i < 5; i++) {
        printf(“%2d”, Ahead->val);
        Ahead = Ahead->next;
    }
}
void reveral(struct ListNode* p, struct ListNode* q, struct ListNode* Ahead) { 
    if (q == NULL)return;
     {//q为当前插入的点;
        p = q->next;
        q->next = Ahead->next;
        Ahead->next = q;
        q = p;
      }
     reveral(p, q, Ahead);
}
*/

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
思路:迭代,双指针
代码如下:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    struct ListNode *p=l1,*q=l2,*head;
    struct ListNode *temp=(struct ListNode*)malloc(sizeof(struct ListNode));
    head=temp;
    if(p==NULL||q==NULL){
        return p=NULL?q:p;
    }
    if(p==NULL&&q==NULL)return false;
    while(p&&q){
        if(p->val>=q->val){
            temp->next=q;//链接;
            temp=temp->next;//将temp移动到当前点位;
            q=q->next;//移动双指针;
        }
        else{
            temp->next=p;
            temp=temp->next;
            p=p->next;
        }
    }
    temp->next=(p==NULL?q:p);//链接剩下的元素;
    p=head->next;  
    free(head);//释放内存并野指针赋空;
    head=NULL;
    return p;
}
补充:释放内存后:

free(str)后指针仍然指向原来的堆地址,即你仍然可以继续使用,但很危险,因为操作系统已经认为这块内存可以使用,他会毫不考虑的将他分配给其他程序,于是你下次使用的时候可能就已经被别的程序改掉了,这种情况就叫“野指针”,所以最好free()了以后再置空str = NULL;即本程序已经放弃再使用他。何谓“野指针”,在这里补充一下。
野指针是指程序员或操作者不能控制的指针。野指针不是NULL指针,而是指向“垃圾”的指针。
造成“野指针”的原因主要有
1.指针变量没有初始化,任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。在初始化的时候要么指向合法的指针,要么指向NULL。
2.指针变量被free或delete之后,没有设置为NULL。它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。通常会用语句if
(p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。上文DEMO则是这种情况。
3.指针操作超越了变量的作用范围。
  注意其生命周期。

661. 图片平滑器

难度简单

包含整数的二维矩阵 M 表示一个图片的灰度。你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽可能多的利用它们。

示例 1:

输入:
[[1,1,1],
 [1,0,1],
 [1,1,1]]
输出:
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]
解释:
对于点 (0,0), (0,2), (2,0), (2,2): 平均(3/4) = 平均(0.75) = 0
对于点 (0,1), (1,0), (1,2), (2,1): 平均(5/6) = 平均(0.83333333) = 0
对于点 (1,1): 平均(8/9) = 平均(0.88888889) = 0

注意:

  1. 给定矩阵中的整数范围为 [0, 255]。
  2. 矩阵的长和宽的范围均为 [1, 150]。
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** imageSmoother(int** M, int MSize, int* MColSize, int* returnSize, int** returnColumnSizes){
    if (MSize == 1 && *MColSize == 1){
        *returnSize = 1;
        ** returnColumnSizes = 1;
        return M;
    }
    int **res = (int**)malloc(sizeof(int*)*MSize);
    *returnSize = MSize;
    for (int i = 0; i < MSize; i++){
        res[i] = (int*)malloc(sizeof(int)*(*MColSize));
        (*returnColumnSizes)[i] = *MColSize;
    }
    for (int i = 0; i < MSize; i++)
        for (int j = 0; j < *MColSize; j++)
            if (MSize == 1)
                res[i][j] = M[i][j];
            else if (i == 0 && MSize>1)
                res[i][j] = M[i][j] + M[i + 1][j];
            else if (i != 0 && i + 1 < MSize)
                res[i][j] = M[i][j] + M[i – 1][j] + M[i + 1][j];
            else if (i != 0 && i + 1 == MSize)
                res[i][j] = M[i][j] + M[i – 1][j];  
    for (int i = 0; i < MSize; i++)
        for (int j = 0; j < *MColSize; j++)
            if (*MColSize == 1)
                M[i][j] = res[i][j];
            else if (j == 0 && *MColSize>1)
                M[i][j] = res[i][j] + res[i][j + 1];
            else if (j != 0 && j + 1 < *MColSize)
                M[i][j] = res[i][j] + res[i][j – 1] + res[i][j + 1];
            else if (j != 0 && j + 1 == *MColSize)
                M[i][j] = res[i][j] + res[i][j – 1];        
    for (int i = 0; i < MSize; i++)
        for (int j = 0; j < *MColSize; j++)
            if ((MSize == 1 || *MColSize == 1) && (i + j == 0 || i + j + 2 == MSize + *MColSize))
                res[i][j] = M[i][j] / 2;
            else if ((MSize == 1 || *MColSize == 1) && (i + j > 0 && i + j + 2 < MSize + *MColSize))
                res[i][j] = M[i][j] / 3;
            else if ((MSize > 1 && *MColSize > 1) && ((i + j == 0) || (i + j + 2 == MSize + *MColSize) || (i == 0 && j == *MColSize – 1) || (i == MSize – 1 && j == 0)))
                res[i][j] = M[i][j] / 4;
            else if ((MSize > 2 && *MColSize > 2) && (i > 0 && i < MSize – 1 && j>0 && j < *MColSize – 1))
                res[i][j] = M[i][j] / 9;
            else
                res[i][j] = M[i][j] / 6;    
    return res;
}

给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。
示例 1:
输入:”ab-cd”
输出:”dc-ba”
示例 2:
输入:”a-bC-dEf-ghIj”
输出:”j-Ih-gfE-dCba”
示例 3:
输入:”Test1ng-Leet=code-Q!”
输出:”Qedo1ct-eeLg=ntse-T!”
char * reverseOnlyLetters(char * S){
    //可以用isalpha函数宏定义(islower小写isupper大写)判断是否为字母;
    int i=0,j=strlen(S)-1;//双指针,一个头一个尾;
    if(j<=0)return S;
    while(i<=j){
        if(isalpha(S[i])&&isalpha(S[j])){//双指针所指向都是字母;
            char temp=S[i];
            S[i++]=S[j];
            S[j–]=temp;
        }//交换,并且指针同时移动;
        //其他留在原地就好了;
        if(!isalpha(S[i])){
            i++;
        }//移动前指针;
        if(!isalpha(S[j])){
            j–;
        }
    }
    return S;
}
宏定义和函数:
不同。虽然功能近似,但bai函数会产生独立代码,每du次调用执行的zhi是同一个位置的代码,无论调用多少次dao。宏定义是简单的文本替换,产生的代码是替换后程序产生的代码,简单说就是程序里每次使用宏替换后的地方都要产生类似的代码,而这些替换后产生的代码存在于程序的不同位置。宏定义不检查参数类型,仅仅是简单的文本替换

C语言函数指针和指针函数的区别
C和C++中经常会用到指针,和数据项一样,函数也是有地址的,函数的地址是存储其机器语言代码的内存的开始地址。
指针函数和函数指针经常会混淆,一个是返回指针的函数,另一个是指向函数的指针,下面就分别解释指针函数和函数指针的区别。
一、指针函数
指针函数是 返回指针的函数 主体是函数,返回值是一个指针
基本声明形式:返回数据类型 + * + 函数名 + (变量类型1,…);
e.g :
int* fun(int,int);
int * fun(int,int);
int *fun(int,int);
123
这三种声明都可以,第一种更加直观 返回值是 int* 类型
举个栗子:
#include<stdio.h>
int* fun(int* x)    //传入指针
{
int* tmp = x;   //指针tmp指向x
return tmp;       //返回tmp指向的地址
}
int main()
{
int b = 2;
int* p = &b;   //p指向b的地址
printf(“%d”,*fun(p));//输出p指向的地址的值
return 0;
}
12345678910111213
输出结果:2
二、函数指针
函数指针是 指向函数的指针 主体是指针 指向的是一个函数的地址
基本声明形式:返回数据类型 + (*函数名) + (变量类型1,…);
注意 * 和函数名要用括号括起来,否则因为运算符的优先级原因就变成指针函数了
e.g:
int (*fun) (int);
1
#include<stdio.h>
int add(int x,int y)
{
return x + y;
}
int (*fun) (int,int);   //声明函数指针
int main()
{
fun = &add;     //fun函数指针指向add函数
printf(“%d “,fun(3,5));
printf(“%d”,(*fun)(4,2));
return 0;
}
12345678910111213
输出结果:8 6
上面的样例中,使用函数指针时使用fun(3,5)和(*fun)(3,5)都可以
函数指针的参数列表要和函数指针指向的函数的参数列表一致
主要记住指针函数是返回指针的函数
而函数指针是指向函数的指针
在这个基础上可以有函数指针函数和指针函数指针之类的
指针函数声明的时候 * 和函数名不需要括号括起来
函数指针声明的时候  * 需要和函数名用括号括起来(优先级原因)